From 2cd80aa8adcde06668a9c8984c9a7a04a843f5ce Mon Sep 17 00:00:00 2001 From: Mike Wiebe Date: Tue, 14 Mar 2017 10:09:58 -0400 Subject: [PATCH] Release 1.6.0 (#437) * Added IOS XR support for tacacs_server * Updated CHANGELOG * Update CHANGELOG.md * Added support on IOS XR for tacacs_server_group * remove sync damage from demo_bridge * Refactored network_interface provider. Updated tests and code to support IOS XR. * Matrix updates for overlay_global & network_trunk * domain and search options are mutually exclusive http://man7.org/linux/man-pages/man5/resolv.conf.5.html * Remove source_interface_hold_down_time for 8k * Collapse release_1.3.2 to develop * cisco_bfd_global: new properties (#334) * manifest * type file add * provider file * array types * beaker * add loopback int * remove name * fix manifest * documentation * comment * Review comments * Fix README * Fix README * network_snmp ios_xr does not support global enable * bgp_neighbor: add bfd (#340) * manifest * type file add * provider file * array types * beaker * add loopback int * remove name * fix manifest * documentation * comment * Review comments * Fix README * Fix README * add bfd to bgp_neighbor * bfd prop * documentation * Fix BFD caveat * Update CHANGELOG.md * search_domain, tests platform agnostic (#343) * modificatins for snmp_notification on IOS_XR * test fixes for ios_xr snmp_notification_receiver (#338) * Add test_get / test_set to command_config (#348) * Add test_get / test_set to command_config * Needed a way for beaker to query / set config that didn't have explicit resource support (e.g. disabling a feature) * test_get is a simple get-only property that does a show running; callers set a filter to parse what they need: `puppet resource cisco_command_config 'cc' test_get='incl feature'` * test_set is a simple set-only property: `puppet resource cisco_command_config 'cc' test_set='no feature foo'` * Tested on n3,n5,n7,n9 * Bad regex in bkr test service_provider_nondefaults.rb * Add beaker test_get / test_set * config_find_remove() uses test_get to search for existing configs, then test_set to remove it. * Fix the fabricpath tests which ran into an issue on n5k when cleaning up 'feature nv overlay' with command_config: Puppet resource removes the config but then immediately does a 'show runn' which gets a SAP timeout on the device itself and the test errors. Using the test_set setter instead of regular command_config gets around this problem because it's a "set-only" with a dummy test_set getter. * Tested on n5,n7,n9 * test_get: add debugs, comments * tested on n5 * Skipped tacacs provider test on IOS XR (#350) * Refactor tests: aaa_group_tacacs (#351) * Converted to new test syntax * Tested on n9-i4 * Add cisco_ospf_area provider (#352) This PR is for cisco_ospf_area provider. The properties do not include nssa and its associated properties. They will be added as part of another user story. Since this provider becomes absent when all properties are set to default, cisco_pim model is followed for beaker tests. All demo_manifests and beaker tests passed on all platforms. Squashed commits: * first commit * fix issues * remove comment * Fix stub * fix area to ipaddr or int * small error * beaker tests * documentation * review comments * Update README.md * Review comments about stub * Added IOS XR support for snmp_user (#353) * Add nssa properties to ospf_area provider (#354) * first commit * fix issues * remove comment * Fix stub * fix area to ipaddr or int * small error * beaker tests * documentation * review comments * Update README.md * Review comments about stub * nssa * small correction * name changes * fix manifest * fix nssa_set * include cmnutils * beaker test added for nssa * typo fix * documentation * fix docmentation * fix README * Fix review comments * tacacs_global changes for ios_xr (#342) * router_ospf_area_vlink: new provider (#355) Adds virtual-link support * Fixes for cisco_interface_ospf provider (#357) * Fix interface_ospf provider and beaker * doc * doc * review comments * minor vrf name change * to avoid annoying conflict with 'management' * command_config: undefined method 'previous' (#358) * Symptom: Simple cc manifest with a faulty line of config: cisco_command_config { 'interface': command => ' interface loopback42 ipv6 pim foo ' } When puppet agent runs the cc provider drops into a rescue which should first print out the parts of the config that were successfully processed and then do a raise, but instead we see: ``` Error: undefined method 'previous' for # ``` * Analysis: `client.rb` was refactored a few months ago, wherein the `previous` hash key was renamed to `successful_input`. The cc providers (both puppet & chef) never got updated with the new key name. * Ref: https://github.com/cisco/cisco-network-node-utils/blob/develop/lib/cisco_node_utils/client/nxapi/client.rb#L285 * Testing: ``` Linux# puppet agent -t --debug ... Info: Cisco_command_config[interface](provider=cisco): Successfully updated: interface loopback42 Error: The command 'ipv6 pim foo' was rejected with error: % Invalid command Error: /Stage[main]/Main/Node[default]/Cisco_command_config[interface]/command: change from to interface loopback42 ipv6 pim foo failed: The command 'ipv6 pim foo' was rejected with error: % Invalid command ``` * Merge release_1.3.2 --> develop (#365) * Add note on existing_str * Refactor test_interface.rb into multiple files * This test was trying to do too much; it became too large and unwieldy to use and troubleshoot. * Refactor to use new test syntax (test_harness_run) * File changes: * deleted: test_interface.rb * new file: interfacelib.rb * new file: test_interface_L2.rb * new file: test_interface_L3.rb * new file: test_interface_bdi.rb * modified: test_interface_capabilities.rb * modified: test_interface_stp.rb * new file: test_interface_svi.rb * new file: test_interface_private_vlan.rb * renamed test_vlan_mapping.rb to test_interface_vlan_mapping.rb * Only tested on n7k and n9k so far but there's a lot here and I wanted to get some eyes on the changes * Platform tweaks for test_interface* * test_interface: add skip_unless_supported plat checks * Minor change to bail out of the test immediately if the platform does not apply * test_interface_private_vlan: fix trunk assoc cleanup * Found a bug on n9k where 'private-vlan association trunk' does not get cleaned up by 'default interface', which breaks this beaker test * Created a workaround cleanup method that does 'no switchport' * Tested on N9k-I3 * test_private_vlan: refactor, remove redundancies * Refactored to use new test syntax; removed unnecessary/redundant tests and some that didn't test anything * This test suffers from the same idempotency bug as the interface private-vlan code; it will require the same kind of fix * Tested on n9k-I3, N7 * Bump version number. * Add testing for switchport_autostate_exclude * Remove old and redudant access_vlan tests * Remove old style beaker tests * normalize_range_array for puppet This is the puppet counter-part to NU. The notes below are copied from: https://github.com/cisco/cisco-network-node-utils/pull/400 The main difference between these is a default check in Utils.normalize_range_array and that there's no Utils.dash_range_to_elements since that's not needed in puppet. * The motivation for this change was finding yet another array normalizer in the private vlan code so these changes are initially meant to address fixes there. IMO our range summarize methods were getting a bit long and difficult to maintain; these new methods will hopefully simplify things somewhat. * The main problem these methods are trying to solve is reconciling manifest inputs with getter results when there are overlapping ranges; e.g.: * '2-5, 9, 4-6' needs to be ['2-6', '9'] * ['2', '3', '4-6'] needs to be ['2-6'] * ['2', '3', '4'] needs to be ['2-4'] * It's fairly easy to merge the ranges if they are actual ruby ranges instead of the dash-syntax ranges, so the new methods just convert to ruby ranges, merge, and convert back. * Tested on n9k. Additional testing coming on the other platforms, as well well as demo, Readme, etc. * bgp_af l2vpn * Fix demo_bgp * Fix additional_paths_install * New beaker style vlan tests * l2vpn/evpn support * l2vpn/evpn support * exclude n3k * review comments * Review comments * cisco_interface: deprecate private_vlan* * private_vlan refactor * cisco_interface: private_vlan refactor * Deprecated the private_vlan properties that were released with 1.3.0 and created new pvlan properties in their place. * This is the companion to NU PR: https://github.com/cisco/cisco-network-node-utils/pull/406 * Updated Type, Provider, Beaker, Demo, README, and CHANGELOG. * Currently only tested on N7, N9-i3. Additional testing in prog. * readme and changelog * readme and changelog * Update README.md * pvlan beaker fixups for 6k * The 6k cli is strict about requiring vlan associations before allowing interface vlan association; therefore I added the dependencies to the test. I need to rerun the test on all the platforms to see if the platform check needs to be tweaked. * Only tested on n6 so far * Minor demo_interface changes * Added some private-vlan dependency resources * test_interface_private_vlan: n3k platform fixes * demo manifest as well * tested on n3-i4,n9-i2,n5,n9-i3,n7 * test_interface_stp needs vlan cleanup * tested on n9-i3 * Re-add n8k doc references * Fix some N8k references * Add N8k back to support table * Remove extra property * Fix spacing in rotate property * anycast_gateway platform checks * Restrict the anycast test to n9k only * Tested on n3,n7,n9-i2,n9-i3 * test_interface_service_vni script fixes * Some cleanup / setup was insufficient * :non_default was not getting run * This is only supported on n7k; tested on n7k. * test_vrf: f3 dependencies * N7k needs an f3-only vdc for route_distinguisher * tested on n7 * test_vrf_af: add f3 dependency for 7k * tested on n7k * Update README-agent-install.md * Update README.md * test_vlan/test_private_vlan: add f3 deps * Tested on n7 * test_vxlan_vtep*: add f3 deps * Tested on n7 * Refactor package provider to use rpm - qip (#328) * Replace regexp with rpm -qip * patching demo updates * Updated fail message * Update demo_patching.pp * Add back rpm filename regexp support (#329) * Add back rpm filename regexp support * Remove debugs * Update README.md * interface svi fix * Remove explicit anycast config * anycast-gateway-mac is a required dependency; a recent commit added an explicit call to the test file to set this up; BUT we already had existing code for doing this that was part of interfacelib.rb * The interfacelib code was returning early because of /unless/if/ * Tested on n9-i4 * test_interface_L2 should reset sys_def_switchport * This test sets the system default switchport state to true but it should reset it to false when it's finished. * Tested on n9-i4 * test_vxlan_vtep_vni: suppress_uuc broken * There was a platform exception that tried to add this property using the new test syntax; however this test file uses an older syntax. * Added an nv overlay hw support check (my n6k does not support nv overlay) * Tested on n6 * README-agent-install: doc cleanup (#330) * README-agent-install: doc cleanup * This doc has had a lot of misc updates in the past so I tried to streamline the content somewhat and organize the sections into discrete steps. * A couple of things that need a closer look: * The RPM table may need updating to reflect the GS fix coming out any day * The auto-install section for cisco_node_utils gem is a little weak. I'm not sure if I referenced the correct pp file and used the right directory target. * README-agent-install.md: Cleanup node-utils section * README-agent-install.md: fix broken links * Review comments addressed * All addressed except for the GS RPM comment. * README-agent-install: GS RPM v1.5 tested * Add markdown syntax flags * README.md cleanup for 1.3.2 (#335) * Move Document Workflow Map to Documentation Guide table * README: Move Limitations into Platform Support * Add Legend & tables * README: Update Usage section * README: Move platform support section after resource ref tables * README.md: minor text change * URL change: /develop/master/ * Addressed remaining PR comments * /develop/master/ URL fixup * test_vdc: fix for non-F3 testbeds (#336) * test_vdc: fix for non-F3 testbeds * Updated this test to work with non-F3 N7k testbeds. * Initially set the VDC module-type to default state * Then set module-type to F3 and test * There's no great way to know which way to leave the module-type when this test completes, so: * Reset module-type to default for non-F3 testbeds since leaving it as F3 means the device won't have any usable interfaces * Noop for F3 testbeds so that it leaves their F3 still usable * Tested on n6, n7-non-F3 * beaker tests: add F3 dependencies * vdc, bridge-domain tests * tested on n6, n7-non-F3 * Fix vxlan_vtep_vni suppress_uuc prop (#341) * Readme.md changes for itd_service (#346) * itd_service pre requisite * cleanup * cleanup * review comment * review comment * review comment * Add n8k reference to CHANGELOG * command_config: undefined method 'previous' (#358) * Symptom: Simple cc manifest with a faulty line of config: cisco_command_config { 'interface': command => ' interface loopback42 ipv6 pim foo ' } When puppet agent runs the cc provider drops into a rescue which should first print out the parts of the config that were successfully processed and then do a raise, but instead we see: ``` Error: undefined method 'previous' for # ``` * Analysis: `client.rb` was refactored a few months ago, wherein the `previous` hash key was renamed to `successful_input`. The cc providers (both puppet & chef) never got updated with the new key name. * Ref: https://github.com/cisco/cisco-network-node-utils/blob/develop/lib/cisco_node_utils/client/nxapi/client.rb#L285 * Testing: ``` Linux# puppet agent -t --debug ... Info: Cisco_command_config[interface](provider=cisco): Successfully updated: interface loopback42 Error: The command 'ipv6 pim foo' was rejected with error: % Invalid command Error: /Stage[main]/Main/Node[default]/Cisco_command_config[interface]/command: change from to interface loopback42 ipv6 pim foo failed: The command 'ipv6 pim foo' was rejected with error: % Invalid command ``` * New overlay_global behaviors (#360) * DME changes for l2rib properties resulted in removal of the 'default' keyword from the cli: `l2rib dup-host-mac-detection default` * Prior to this change, 'default' was the only way to reset the host_moves & timeout properties back to default; there was/is no 'no' command, so the only way to reset it now is to re-enter the command with the default values. * This change necessitates changes to the setter, minitest, and beaker. I also changed the default values to actual integer values instead of empty strings. * Tested minitest & beaker for: n9-edev,n9-I4,n5,n6. Skips for n3 (normal) and n7 (requires F3 card). * Remove vsh code (#361) * Fix cisco_aaa* 'TACACS+ group delete denied, group is in use' issue (#362) * Added setup and cleanup steps * Add back needed autorequires * Added cleanup and teardown calls * Refactor setup/cleanup * Remove debug causing beaker tests to error out * Fix cisco_tacacs* 'TACACS+ group delete denied, group is in use' (#363) * Added setup and cleanup steps * Add back needed autorequires * Added cleanup and teardown calls * Refactor setup/cleanup * Remove debug causing beaker tests to error out * Add setup/cleanup steps * Fix netdev tacacs* 'TACACS+ group delete denied, group is in use' (#364) * Added setup and cleanup steps * Add back needed autorequires * Added cleanup and teardown calls * Refactor setup/cleanup * Remove debug causing beaker tests to error out * Add setup/cleanup steps * Add setup/cleanup steps * Fixed merge issue * Add noop beaker test * This is a dummy test for use during CI development * Move noop.rb to base dir * Munge events value 'false' to 'size_disable' (#366) Due to recent platform changes, the CLI for `event_history events size disable` now results in the config `no event-history events`. This change munges the manifest value of `false` to `size_disable`. * Ospf bfd for interfaces (#367) * Fix interface_ospf provider and beaker * doc * doc * review comments * bfd added to router ospf vrf * bfd_per_link added to interface_portchannel * add bfd and network to int ospf * add bfd echo to intf * changelog * doc * Remove get_vshell_cmd calls (#368) * L3 PIM-on-VRF-intf beaker fix (#369) * ip pim sparse-mode was failing to nvgen during the test * Factors: a) the intf is in vrf 'test1'; and, b) 'test1' has not been instantiated yet * Normally these forward-references are not a problem but the new DME-based PIM cli is silently rejecting it because the vrf is not instantiated * For puppet it's not unreasonable to require a pre-instantiated vrf, and since this change only affects our beaker test I'm just going to update the test. The PIM team did say they would reconsider raising an error for this, or better yet just create the pim cli object regardless of vrf-instantiation state. * Also fixed a cleanup issue for dot1q sub-ints. * Tested on N9-I5 * Add Ospf properties for interfaces (#371) * Fix interface_ospf provider and beaker * doc * doc * review comments * add mtu, pri, shut and tx delay to int ospf * documentation * Fix beaker test bug (#372) * bug fix for interface_portchannel beaker test (#373) * Fix interface_ospf provider and beaker * doc * doc * review comments * add mtu, pri, shut and tx delay to int ospf * documentation * bug fix * Removed, no longer needed * Remove broken snmp_user XR support (#374) * Add agent_probe to utility.lib (#375) * `feature vn-segment-vlan-based` is not supported on some n3k's * Added a simple helper method to test for h/w support; the result is then used by `unsupported_properties` to update the test cases * Tested on n3k(3048), n7k, n9k * Add f3 utility for n7 bkr tests (#376) * Tested on n7k * Fix half/full in test_duplex (#377) * For some 3k, need to munge 'half/full' into csv-style 'half,full' to play nice with interface_capabilities * This fix is a little trickier than the NU fix because the output from puppet resource is 'raw' whereas the NU output is a pre-processed hash of capabilities; thus we have to be careful not to munge the vsh or puppet resource output. * Tested on n3048 * Update service provider beaker test to work in guestshell (#378) * Select service based on OS family * Update fail_test message * Add teardowns to beaker (#379) * f3 handling for test_vrf (#380) * f3 handling for test_vrf * N7k setup/cleanup when missing F3 cards * New `image?` method for checking image version pattern; used as test for unprops * New `remove_all_vrfs` method that uses `test_get`/`test_set`; this is much faster than removing vrfs one at a time * Remove :description image check * Remove redundant cleanup * f3 setup/teardown for vrf_af * f3 setup/teardown bridge-domain * f3 setup/teardown for encap * bkr setup/teardown cleanups * f3 setup/teardown for interface_svi * f3 setup/teardown for service_vni * f3 setup/teardown test_private_vlan * f3 setup/teardown for vxlan_vtep* * f3 setup/teardown for fabricpath_topology * setup/teardown cleanups for cisco_itd_device_group_node * beaker fix for resilient and symmetry non support on n3k (#381) * Fix interface_ospf provider and beaker * doc * doc * review comments * add mtu, pri, shut and tx delay to int ospf * documentation * bug fix * Fix for symmetry and resilient no support on n3k * review comment * rewview comments * setup/teardown for bfd_global * setup/teardown bridge_domain * setup/teardown acl * setup/teardown bgp_af * setup/teardown cisco_pim * Convert test_fabricpath_global to new syntax * Setup/teardown test_interface_L3 * setup/teardown test_interface_private_vlan * Convert test_interface_channel_group to new syntax * Convert test_interface_portchannel to new syntax * setup/teardown for test_itd_service * setup/teardown cisco_ospf_area* * setup/teardown cisco_interface_ospf * setup/teardown cisco_ospf_vrf * Bad cleanup test_itd_service * Convert test_command_config to new syntax * better cleanup for bfd * setup/teardown for test_bgp * setup/teardown test_bgpaf * better cleanup for pim * setup/teardown test_bgpneighbor * Better remove_all_vlans * setup/teardown test_bgpneighboraf * ospf_vrf cleanup should remove feature bfd * setup/teardown test_stp_global * setup/teardown test_bgpneighbor* * better cleanup test_interface_L3 * better cleanup test_interface_ospf * setup/teardown test_interface_portchannel * setup/teardown test_interface_stp * setup/teardown test_interface_bdi * setup/teardown test_evpn_vni * Convert test_vpc_domain to new syntax * setup/teardown test_itd_device_group * Convert test_overlay_global to new syntax * Rel140/refactor package tests (#382) * Refactor beaker package tests * Remove unused code * Rubocop fix * Uncomment filename * Add ensure_prop_override setting * Rubocop fix * Fix test_itd_service * The cleanup in the dependency manifest was turning off 'feature itd' but that needs to be re-enabled in order to configure the itd device-group dependency * beaker: Remove raise_skip call from summary checker * test_interface_ospf dependency fix * Add :array opt to test_get bkr utility * Enable yum package testing in guestshell (#384) * Initial gs package test support * Minor refactoring * Add camden i2.1 patch details * Use specific yum patch for camden fcs * Separate native and gs test flow * Remove ensure absent in manifest_props * Enable additional releases * I5 patch fix * Use single workflow for gs and native * Convert test_snmp_server to new syntax (#385) * Convert test_snmp_server to new syntax * packetsize was failing on n7k so I just rewrote the test to use the new format * tested on n7k,n9k-I5 * Fix pktsize cleanup * Rename test_package.rb -> test_package_patch.rb * Converted the old style tests to new syntax. (#386) Most of these are straightforward changes. The package test is complicated on native since third-party rpms require setting up a yum repo, but I set up the test to do the repo init via puppet so we actually get a bit more coverage this way. * Tested on N5,N7,N9-I5 using native/GS/OAC * utilitylib: Restore tests[id][:resource]['ensure'] I pulled this out by mistake with this commit: https://github.com/cisco/cisco-network-puppet-module/commit/2641c7a1c821b9b512510ad3a2952f5dbfe7c0fd#diff-e0883d3270eb11e5d50fcdc5c4f83003L603 * test_interface_ospf: Fix process dependency * A previous test cleanup removed 'router ospf Sample' from the harness dependencies; now the nightly if failing when it tries to configure an ospf config on an interface * Although the router config is not necessary for the interface config, the failure occurs because the ospf process is still starting up (ospf startup is slow on 5k/6k/8k). The ospf provider already has a 'wait_for_process_initialized' method to handle this slow start, while the interface_ospf provider does not. This is only an issue during testing so I do not propose adding the wait_for method to interface_ospf. * Tested on n5,n7,n9 * test_interface_ospf: Fix process dependency (#388) * A previous test cleanup removed 'router ospf Sample' from the harness dependencies; now the nightly if failing when it tries to configure an ospf config on an interface * Although the router config is not necessary for the interface config, the failure occurs because the ospf process is still starting up (ospf startup is slow on 5k/6k/8k). The ospf provider already has a 'wait_for_process_initialized' method to handle this slow start, while the interface_ospf provider does not. This is only an issue during testing so I do not propose adding the wait_for method to interface_ospf. * Tested on n5,n7,n9 * Add log.error to beaker search_pattern * When test_resource fails it just displays what it's expecting to find but it doesn't show what the current output was (which often helps with troubleshooting). This just includes the output when there's a failure. * Add titles for bgp vrf beaker tests * Suppress fib pending fix (#387) * Generalize the method for checking nexus images * Fix suppress fib pending for non-I5 images * Clean up image check and post-merge leftovers * cisco_interface enhancement (#389) * Fix interface_ospf provider and beaker * doc * doc * review comments * add mtu, pri, shut and tx delay to int ospf * documentation * bug fix * Fix for symmetry and resilient no support on n3k * review comment * rewview comments * dhcp relay and storm control -- not tested yet * beaker test * fix non default test * removed storm control broadcast and multicast for n7k * fix munging * demo manifest changes * cleanup manifests * dhcp and l3 are merged * merge L2 and storm control * docs * review comments * Add'l cleanup for test_interface_ospf * Fix id bug * Replace skip_nexus_i2_image() with skip_nexus_image() api call (#390) * Skip dns provider test instead of error * Remove commented out call to fail api * Update test_harness_dependencies for test_interface_ospf.rb (#393) * Fixed rubocop errors * Remove debug code * Dhcp Relay Global (#392) * Fix interface_ospf provider and beaker * doc * doc * review comments * add mtu, pri, shut and tx delay to int ospf * documentation * bug fix * Fix for symmetry and resilient no support on n3k * review comment * rewview comments * dhcp relay and storm control -- not tested yet * beaker test * fix non default test * removed storm control broadcast and multicast for n7k * fix munging * demo manifest changes * cleanup manifests * dhcp and l3 are merged * merge L2 and storm control * docs * review comments * dhcp_relay_global provider * beaker * fix beaker * Fix provider code for removal of name * documentation * typo in beaker * fix doc * fix doc * fix doc for version * Remove packet_size prop testing for I2 and I3 images * cisco_interface beaker test (#394) * Fix interface_ospf provider and beaker * doc * doc * review comments * add mtu, pri, shut and tx delay to int ospf * documentation * bug fix * Fix for symmetry and resilient no support on n3k * review comment * rewview comments * dhcp relay and storm control -- not tested yet * beaker test * fix non default test * removed storm control broadcast and multicast for n7k * fix munging * demo manifest changes * cleanup manifests * dhcp and l3 are merged * merge L2 and storm control * docs * review comments * dhcp_relay_global provider * beaker * fix beaker * Fix provider code for removal of name * documentation * typo in beaker * fix doc * fix doc * fix doc for version * fix beaker test for intf * event_history_periodic changes for bgp (#395) * Fix interface_ospf provider and beaker * doc * doc * review comments * add mtu, pri, shut and tx delay to int ospf * documentation * bug fix * Fix for symmetry and resilient no support on n3k * review comment * rewview comments * dhcp relay and storm control -- not tested yet * beaker test * fix non default test * removed storm control broadcast and multicast for n7k * fix munging * demo manifest changes * cleanup manifests * dhcp and l3 are merged * merge L2 and storm control * docs * review comments * dhcp_relay_global provider * beaker * fix beaker * Fix provider code for removal of name * documentation * typo in beaker * fix doc * fix doc * fix doc for version * fix beaker test for intf * fix bgp for event_history * move facter to provider * beaker for event_history_periodic * documentation * review comments * review comments * bgp event_history (#400) * fix bgp event-history * beaker changes * doc and manifest * review comments * manifest review comment * Rel141/lacp suspend (#401) * Fix lacp_suspend_individual property issue in evergreen * Remove unneeded test_set call in test_interface_portchannel.rb * Update README.me with lacp_suspend_individual caveat * Futher clarify caveat for lacp_suspend_individual property * Futher clarify caveat for lacp_suspend_individual property * Test non-default value for n3k * fix vrf beaker (#402) * Remove comment that no longer applied with the latest node utils gem * Scrub N8k References * hsrp_global and interface hsrp (#404) * hsrp global new provider * hsrp interface * beaker of intf_hsrp * move int_hsrp to int * documentation * Rel150/n8k n9kf rebranding (#406) * N8k -> N9K-F changes * Fix puppet module function name * Remove old README doc * Update N9k-F Module Version * Additional N8k -> N9K-F updates * Refactor platform_fretta function to use os_release fact * Update platform_fretta function comments * Fix image version check * Skip privte vlan tests on n9k-f * Skip cisco_itd tests on n9k-f * Skip private vlan tests on n9k-f * Skip cisco_vpc tests on n9k-f * Anchor n9k platform check * Update platform regexp to use correct packet size for fretta * Rel150/product tag (#407) * Add product_tag helper method * Fix bug in product_tag api * Update CHANGELOG.md * Interface HSRP group (#405) * hsrp global new provider * hsrp interface * beaker of intf_hsrp * move int_hsrp to int * documentation * hsrp group fixes * fix array issue * add validations * demo manifest * beaker * documentation * n8k to n9k-f * review comments * fix event_history for fretta * fixes for review comments * readme change * more comments * Rel150/atherton fretta fixes (#409) * Handle atherton nxapi double quotes * Handle atherton nxapi double quotes * Handle atherton nxapi double quotes for tacacs * Make regexp in nexus_image method more flexible * pim and interface bfd (#410) * pim bfd * doc * Update CHANGELOG.md * n7k atherton hsrp (#411) * pim bfd * doc * fix n7k atherton hsrp * review comments for doc * review comments for doc * Add ('--') separator for /bin/nsenter example. Resolves https://github.com/cisco/cisco-network-puppet-module/issues/413 * Update Copyright date * fix the case sensitive issue for int_hsrp_group (#416) * cisco route map (#418) * pim bfd * doc * fix n7k atherton hsrp * review comments for doc * review comments for doc * partial new code * rest of the code * manifest * fix get issue * fix few errors in manifest * fix manifest * fix few issues * fix next-hop sets * fix manifest * fix few issues * fix vlan string munge * beaker tests * fix manifest * fix beaker * fix case sensitivity for int_hsrp_group name * remove downcase from provider * fixes for fretta * doc * remove 2 props from I4 code * review comments * review comments * fix doc * review comments * add validate for multicast props * route-map provider (#421) * pim bfd * doc * fix n7k atherton hsrp * review comments for doc * review comments for doc * partial new code * rest of the code * manifest * fix get issue * fix few errors in manifest * fix manifest * fix few issues * fix next-hop sets * fix manifest * fix few issues * fix vlan string munge * beaker tests * fix manifest * fix beaker * fix case sensitivity for int_hsrp_group name * remove downcase from provider * fixes for fretta * doc * remove 2 props from I4 code * review comments * review comments * fix doc * review comments * add validate for multicast props * add validate for multicast props * Fix Chrun: console and vty config #417 (#422) * Strip \r characters * Add testcases to validate config with ctrl chars * Remove puts and add inspect to debugs * Add cleanup before next test * Refactor ctrl character pattern and test * Remove puts statements * Add load-interval props to cisco_interface (#425) * add load-interval attribs to interface * clean up changelog * review comment * fix double quotes issue for passwords (#426) * add load-interval attribs to interface * clean up changelog * review comment * double quote string cleanup * review comments * fix backspace issue for dhcp (#428) * Feature/upgrade services (#427) * Add new type for cisco_service * Add new provider cisco_Service * Fix rubopcop errors * fix rubocop errors * Fix date on CopyRight * Rename cisco_service to cisco_upgrade * Redesigned upgrade resource type based on @mikewiebe PR comments * Redesigned upgrade resource provider based on @mikewiebe PR comments * removing cisco_service resource type * rename media to uri and misc. fixes * converting del_boot_image and force_upgrade to bools * Remove whitespace * Source_uri is required * Handle node_utils API change from service to upgrade * Feature/upgrade services (#429) * Add new type for cisco_service * Add new provider cisco_Service * Fix rubopcop errors * fix rubocop errors * Fix date on CopyRight * Rename cisco_service to cisco_upgrade * Redesigned upgrade resource type based on @mikewiebe PR comments * Redesigned upgrade resource provider based on @mikewiebe PR comments * removing cisco_service resource type * rename media to uri and misc. fixes * converting del_boot_image and force_upgrade to bools * Remove whitespace * Source_uri is required * Handle node_utils API change from service to upgrade * Move source_uri validation to provider * remove all route maps after beaker test (#431) * remove all route maps after beaker test * review comment * Feature/upgrade services (#430) * Add new type for cisco_service * Add new provider cisco_Service * Fix rubopcop errors * fix rubocop errors * Fix date on CopyRight * Rename cisco_service to cisco_upgrade * Redesigned upgrade resource type based on @mikewiebe PR comments * Redesigned upgrade resource provider based on @mikewiebe PR comments * removing cisco_service resource type * rename media to uri and misc. fixes * converting del_boot_image and force_upgrade to bools * Remove whitespace * Source_uri is required * Handle node_utils API change from service to upgrade * Move source_uri validation to provider * Added image_version proc and ability to process '()' * Fix rubocop errors * Add new test file for cisco_upgrade resource beaker_tests/cisco_upgrade/test_upgrade_idempotence.rb * Running cisco_upgrade tests on n3k,n9k only * Update README with references to the new cisco_upgrade resource * Update README.md * Add demo manifest for cisco_upgrade * Add new manifest for cisco_upgrade * Added 'cisco_upgrade' to changelog * Update Support Table for cisco_upgrade Add Release for Fretta and update N9K/N3k release to camden 2e * Minor changes to README.md * Update README.md * Minor changes to documentation * Update version -> 1.6.0 * Update CHANGELOG.md * Update metadata.json * Feature/upgrade services (#433) * Add new type for cisco_service * Add new provider cisco_Service * Fix rubopcop errors * fix rubocop errors * Fix date on CopyRight * Rename cisco_service to cisco_upgrade * Redesigned upgrade resource type based on @mikewiebe PR comments * Redesigned upgrade resource provider based on @mikewiebe PR comments * removing cisco_service resource type * rename media to uri and misc. fixes * converting del_boot_image and force_upgrade to bools * Remove whitespace * Source_uri is required * Handle node_utils API change from service to upgrade * Move source_uri validation to provider * Added image_version proc and ability to process '()' * Fix rubocop errors * Add new test file for cisco_upgrade resource beaker_tests/cisco_upgrade/test_upgrade_idempotence.rb * Running cisco_upgrade tests on n3k,n9k only * Update README with references to the new cisco_upgrade resource * Update README.md * Add demo manifest for cisco_upgrade * Add new manifest for cisco_upgrade * Added 'cisco_upgrade' to changelog * Update Support Table for cisco_upgrade Add Release for Fretta and update N9K/N3k release to camden 2e * Minor changes to README.md * Update README.md * Minor changes to documentation * Replace output with stdout.chomp for facter call * Fix radius_global_provider_defaults expected reponses (#434) * Update radius_global_provider_defaults.rb --- CHANGELOG.md | 18 + README.md | 490 +++++ docs/README-agent-install.md | 4 +- examples/cisco/demo_interface.pp | 11 +- examples/cisco/demo_route_map.pp | 401 ++++ examples/cisco/demo_upgrade.pp | 78 + examples/demo_all_cisco.pp | 2 + lib/puppet/feature/cisco_node_utils.rb | 2 +- .../provider/cisco_command_config/cisco.rb | 11 +- lib/puppet/provider/cisco_interface/cisco.rb | 3 + lib/puppet/provider/cisco_route_map/cisco.rb | 557 ++++++ .../provider/cisco_tacacs_server/cisco.rb | 15 + .../cisco_tacacs_server_host/cisco.rb | 15 + lib/puppet/provider/cisco_upgrade/cisco.rb | 82 + lib/puppet/provider/radius_global/cisco.rb | 12 + lib/puppet/provider/radius_server/cisco.rb | 12 + lib/puppet/provider/tacacs_global/cisco.rb | 12 + lib/puppet/provider/tacacs_server/cisco.rb | 12 + lib/puppet/type/cisco_dhcp_relay_global.rb | 6 +- lib/puppet/type/cisco_interface.rb | 28 + lib/puppet/type/cisco_interface_hsrp_group.rb | 1 + lib/puppet/type/cisco_route_map.rb | 1659 +++++++++++++++++ lib/puppet/type/cisco_upgrade.rb | 116 ++ metadata.json | 8 +- .../test_command_config.rb | 23 + .../test_dhcp_relay_global.rb | 2 +- .../cisco_interface/test_interface_L2.rb | 9 + .../cisco_route_map/test_route_map.rb | 571 ++++++ .../cisco_upgrade/test_upgrade_idempotence.rb | 60 + tests/beaker_tests/lib/utilitylib.rb | 12 +- .../radius_global_provider_defaults.rb | 2 +- 31 files changed, 4214 insertions(+), 20 deletions(-) create mode 100644 examples/cisco/demo_route_map.pp create mode 100644 examples/cisco/demo_upgrade.pp create mode 100644 lib/puppet/provider/cisco_route_map/cisco.rb create mode 100644 lib/puppet/provider/cisco_upgrade/cisco.rb create mode 100644 lib/puppet/type/cisco_route_map.rb create mode 100644 lib/puppet/type/cisco_upgrade.rb create mode 100644 tests/beaker_tests/cisco_route_map/test_route_map.rb create mode 100644 tests/beaker_tests/cisco_upgrade/test_upgrade_idempotence.rb 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