1""" 2Network Config 3============== 4 5Manage the configuration on a network device given a specific static config or template. 6 7:codeauthor: Mircea Ulinic <ping@mirceaulinic.net> & Jerome Fleury <jf@cloudflare.com> 8:maturity: new 9:depends: napalm 10:platform: unix 11 12Dependencies 13------------ 14- :mod:`NAPALM proxy minion <salt.proxy.napalm>` 15- :mod:`Network-related basic features execution module <salt.modules.napalm_network>` 16 17.. versionadded:: 2017.7.0 18""" 19 20import logging 21 22import salt.utils.napalm 23 24log = logging.getLogger(__name__) 25 26# ---------------------------------------------------------------------------------------------------------------------- 27# state properties 28# ---------------------------------------------------------------------------------------------------------------------- 29 30__virtualname__ = "netconfig" 31 32# ---------------------------------------------------------------------------------------------------------------------- 33# global variables 34# ---------------------------------------------------------------------------------------------------------------------- 35 36# ---------------------------------------------------------------------------------------------------------------------- 37# property functions 38# ---------------------------------------------------------------------------------------------------------------------- 39 40 41def __virtual__(): 42 """ 43 NAPALM library must be installed for this module to work and run in a (proxy) minion. 44 """ 45 return salt.utils.napalm.virtual(__opts__, __virtualname__, __file__) 46 47 48# ---------------------------------------------------------------------------------------------------------------------- 49# helper functions -- will not be exported 50# ---------------------------------------------------------------------------------------------------------------------- 51 52 53def _update_config( 54 template_name, 55 template_source=None, 56 template_hash=None, 57 template_hash_name=None, 58 template_user="root", 59 template_group="root", 60 template_mode="755", 61 template_attrs="--------------e----", 62 saltenv=None, 63 template_engine="jinja", 64 skip_verify=False, 65 defaults=None, 66 test=False, 67 commit=True, 68 debug=False, 69 replace=False, 70 **template_vars 71): 72 """ 73 Call the necessary functions in order to execute the state. 74 For the moment this only calls the ``net.load_template`` function from the 75 :mod:`Network-related basic features execution module <salt.modules.napalm_network>`, but this may change in time. 76 """ 77 78 return __salt__["net.load_template"]( 79 template_name, 80 template_source=template_source, 81 template_hash=template_hash, 82 template_hash_name=template_hash_name, 83 template_user=template_user, 84 template_group=template_group, 85 template_mode=template_mode, 86 template_attrs=template_attrs, 87 saltenv=saltenv, 88 template_engine=template_engine, 89 skip_verify=skip_verify, 90 defaults=defaults, 91 test=test, 92 commit=commit, 93 debug=debug, 94 replace=replace, 95 **template_vars 96 ) 97 98 99# ---------------------------------------------------------------------------------------------------------------------- 100# callable functions 101# ---------------------------------------------------------------------------------------------------------------------- 102 103 104def replace_pattern( 105 name, 106 pattern, 107 repl, 108 count=0, 109 flags=8, 110 bufsize=1, 111 append_if_not_found=False, 112 prepend_if_not_found=False, 113 not_found_content=None, 114 search_only=False, 115 show_changes=True, 116 backslash_literal=False, 117 source="running", 118 path=None, 119 test=False, 120 replace=True, 121 debug=False, 122 commit=True, 123): 124 """ 125 .. versionadded:: 2019.2.0 126 127 Replace occurrences of a pattern in the configuration source. If 128 ``show_changes`` is ``True``, then a diff of what changed will be returned, 129 otherwise a ``True`` will be returned when changes are made, and ``False`` 130 when no changes are made. 131 This is a pure Python implementation that wraps Python's :py:func:`~re.sub`. 132 133 pattern 134 A regular expression, to be matched using Python's 135 :py:func:`~re.search`. 136 137 repl 138 The replacement text. 139 140 count: ``0`` 141 Maximum number of pattern occurrences to be replaced. If count is a 142 positive integer ``n``, only ``n`` occurrences will be replaced, 143 otherwise all occurrences will be replaced. 144 145 flags (list or int): ``8`` 146 A list of flags defined in the ``re`` module documentation from the 147 Python standard library. Each list item should be a string that will 148 correlate to the human-friendly flag name. E.g., ``['IGNORECASE', 149 'MULTILINE']``. Optionally, ``flags`` may be an int, with a value 150 corresponding to the XOR (``|``) of all the desired flags. Defaults to 151 8 (which supports 'MULTILINE'). 152 153 bufsize (int or str): ``1`` 154 How much of the configuration to buffer into memory at once. The 155 default value ``1`` processes one line at a time. The special value 156 ``file`` may be specified which will read the entire file into memory 157 before processing. 158 159 append_if_not_found: ``False`` 160 If set to ``True``, and pattern is not found, then the content will be 161 appended to the file. 162 163 prepend_if_not_found: ``False`` 164 If set to ``True`` and pattern is not found, then the content will be 165 prepended to the file. 166 167 not_found_content 168 Content to use for append/prepend if not found. If None (default), uses 169 ``repl``. Useful when ``repl`` uses references to group in pattern. 170 171 search_only: ``False`` 172 If set to true, this no changes will be performed on the file, and this 173 function will simply return ``True`` if the pattern was matched, and 174 ``False`` if not. 175 176 show_changes: ``True`` 177 If ``True``, return a diff of changes made. Otherwise, return ``True`` 178 if changes were made, and ``False`` if not. 179 180 backslash_literal: ``False`` 181 Interpret backslashes as literal backslashes for the repl and not 182 escape characters. This will help when using append/prepend so that 183 the backslashes are not interpreted for the repl on the second run of 184 the state. 185 186 source: ``running`` 187 The configuration source. Choose from: ``running``, ``candidate``, or 188 ``startup``. Default: ``running``. 189 190 path 191 Save the temporary configuration to a specific path, then read from 192 there. 193 194 test: ``False`` 195 Dry run? If set as ``True``, will apply the config, discard and return 196 the changes. Default: ``False`` and will commit the changes on the 197 device. 198 199 commit: ``True`` 200 Commit the configuration changes? Default: ``True``. 201 202 debug: ``False`` 203 Debug mode. Will insert a new key in the output dictionary, as 204 ``loaded_config`` containing the raw configuration loaded on the device. 205 206 replace: ``True`` 207 Load and replace the configuration. Default: ``True``. 208 209 If an equal sign (``=``) appears in an argument to a Salt command it is 210 interpreted as a keyword argument in the format ``key=val``. That 211 processing can be bypassed in order to pass an equal sign through to the 212 remote shell command by manually specifying the kwarg: 213 214 State SLS Example: 215 216 .. code-block:: yaml 217 218 update_policy_name: 219 netconfig.replace_pattern: 220 - pattern: OLD-POLICY-NAME 221 - repl: new-policy-name 222 - debug: true 223 """ 224 ret = salt.utils.napalm.default_ret(name) 225 # the user can override the flags the equivalent CLI args 226 # which have higher precedence 227 test = test or __opts__["test"] 228 debug = __salt__["config.merge"]("debug", debug) 229 commit = __salt__["config.merge"]("commit", commit) 230 replace = __salt__["config.merge"]("replace", replace) # this might be a bit risky 231 replace_ret = __salt__["net.replace_pattern"]( 232 pattern, 233 repl, 234 count=count, 235 flags=flags, 236 bufsize=bufsize, 237 append_if_not_found=append_if_not_found, 238 prepend_if_not_found=prepend_if_not_found, 239 not_found_content=not_found_content, 240 search_only=search_only, 241 show_changes=show_changes, 242 backslash_literal=backslash_literal, 243 source=source, 244 path=path, 245 test=test, 246 replace=replace, 247 debug=debug, 248 commit=commit, 249 ) 250 return salt.utils.napalm.loaded_ret(ret, replace_ret, test, debug) 251 252 253def saved( 254 name, 255 source="running", 256 user=None, 257 group=None, 258 mode=None, 259 attrs=None, 260 makedirs=False, 261 dir_mode=None, 262 replace=True, 263 backup="", 264 show_changes=True, 265 create=True, 266 tmp_dir="", 267 tmp_ext="", 268 encoding=None, 269 encoding_errors="strict", 270 allow_empty=False, 271 follow_symlinks=True, 272 check_cmd=None, 273 win_owner=None, 274 win_perms=None, 275 win_deny_perms=None, 276 win_inheritance=True, 277 win_perms_reset=False, 278 **kwargs 279): 280 """ 281 .. versionadded:: 2019.2.0 282 283 Save the configuration to a file on the local file system. 284 285 name 286 Absolute path to file where to save the configuration. 287 To push the files to the Master, use 288 :mod:`cp.push <salt.modules.cp.push>` Execution function. 289 290 source: ``running`` 291 The configuration source. Choose from: ``running``, ``candidate``, 292 ``startup``. Default: ``running``. 293 294 user 295 The user to own the file, this defaults to the user salt is running as 296 on the minion 297 298 group 299 The group ownership set for the file, this defaults to the group salt 300 is running as on the minion. On Windows, this is ignored 301 302 mode 303 The permissions to set on this file, e.g. ``644``, ``0775``, or 304 ``4664``. 305 The default mode for new files and directories corresponds to the 306 umask of the salt process. The mode of existing files and directories 307 will only be changed if ``mode`` is specified. 308 309 .. note:: 310 This option is **not** supported on Windows. 311 attrs 312 The attributes to have on this file, e.g. ``a``, ``i``. The attributes 313 can be any or a combination of the following characters: 314 ``aAcCdDeijPsStTu``. 315 316 .. note:: 317 This option is **not** supported on Windows. 318 319 makedirs: ``False`` 320 If set to ``True``, then the parent directories will be created to 321 facilitate the creation of the named file. If ``False``, and the parent 322 directory of the destination file doesn't exist, the state will fail. 323 324 dir_mode 325 If directories are to be created, passing this option specifies the 326 permissions for those directories. If this is not set, directories 327 will be assigned permissions by adding the execute bit to the mode of 328 the files. 329 330 The default mode for new files and directories corresponds umask of salt 331 process. For existing files and directories it's not enforced. 332 333 replace: ``True`` 334 If set to ``False`` and the file already exists, the file will not be 335 modified even if changes would otherwise be made. Permissions and 336 ownership will still be enforced, however. 337 338 backup 339 Overrides the default backup mode for this specific file. See 340 :ref:`backup_mode documentation <file-state-backups>` for more details. 341 342 show_changes: ``True`` 343 Output a unified diff of the old file and the new file. If ``False`` 344 return a boolean if any changes were made. 345 346 create: ``True`` 347 If set to ``False``, then the file will only be managed if the file 348 already exists on the system. 349 350 encoding 351 If specified, then the specified encoding will be used. Otherwise, the 352 file will be encoded using the system locale (usually UTF-8). See 353 https://docs.python.org/3/library/codecs.html#standard-encodings for 354 the list of available encodings. 355 356 encoding_errors: ``'strict'`` 357 Error encoding scheme. Default is ```'strict'```. 358 See https://docs.python.org/2/library/codecs.html#codec-base-classes 359 for the list of available schemes. 360 361 allow_empty: ``True`` 362 If set to ``False``, then the state will fail if the contents specified 363 by ``contents_pillar`` or ``contents_grains`` are empty. 364 365 follow_symlinks: ``True`` 366 If the desired path is a symlink follow it and make changes to the 367 file to which the symlink points. 368 369 check_cmd 370 The specified command will be run with an appended argument of a 371 *temporary* file containing the new managed contents. If the command 372 exits with a zero status the new managed contents will be written to 373 the managed destination. If the command exits with a nonzero exit 374 code, the state will fail and no changes will be made to the file. 375 376 tmp_dir 377 Directory for temp file created by ``check_cmd``. Useful for checkers 378 dependent on config file location (e.g. daemons restricted to their 379 own config directories by an apparmor profile). 380 381 tmp_ext 382 Suffix for temp file created by ``check_cmd``. Useful for checkers 383 dependent on config file extension (e.g. the init-checkconf upstart 384 config checker). 385 386 win_owner: ``None`` 387 The owner of the directory. If this is not passed, user will be used. If 388 user is not passed, the account under which Salt is running will be 389 used. 390 391 win_perms: ``None`` 392 A dictionary containing permissions to grant and their propagation. For 393 example: ``{'Administrators': {'perms': 'full_control'}}`` Can be a 394 single basic perm or a list of advanced perms. ``perms`` must be 395 specified. ``applies_to`` does not apply to file objects. 396 397 win_deny_perms: ``None`` 398 A dictionary containing permissions to deny and their propagation. For 399 example: ``{'Administrators': {'perms': 'full_control'}}`` Can be a 400 single basic perm or a list of advanced perms. ``perms`` must be 401 specified. ``applies_to`` does not apply to file objects. 402 403 win_inheritance: ``True`` 404 True to inherit permissions from the parent directory, False not to 405 inherit permission. 406 407 win_perms_reset: ``False`` 408 If ``True`` the existing DACL will be cleared and replaced with the 409 settings defined in this function. If ``False``, new entries will be 410 appended to the existing DACL. Default is ``False``. 411 412 State SLS Example: 413 414 .. code-block:: yaml 415 416 /var/backups/{{ opts.id }}/{{ salt.status.time('%s') }}.cfg: 417 netconfig.saved: 418 - source: running 419 - makedirs: true 420 421 The state SLS above would create a backup config grouping the files by the 422 Minion ID, in chronological files. For example, if the state is executed at 423 on the 3rd of August 2018, at 5:15PM, on the Minion ``core1.lon01``, the 424 configuration would saved in the file: 425 ``/var/backups/core01.lon01/1533316558.cfg`` 426 """ 427 ret = __salt__["net.config"](source=source) 428 if not ret["result"]: 429 return {"name": name, "changes": {}, "result": False, "comment": ret["comment"]} 430 return __states__["file.managed"]( 431 name, 432 user=user, 433 group=group, 434 mode=mode, 435 attrs=attrs, 436 makedirs=makedirs, 437 dir_mode=dir_mode, 438 replace=replace, 439 backup=backup, 440 show_changes=show_changes, 441 create=create, 442 contents=ret["out"][source], 443 tmp_dir=tmp_dir, 444 tmp_ext=tmp_ext, 445 encoding=encoding, 446 encoding_errors=encoding_errors, 447 allow_empty=allow_empty, 448 follow_symlinks=follow_symlinks, 449 check_cmd=check_cmd, 450 win_owner=win_owner, 451 win_perms=win_perms, 452 win_deny_perms=win_deny_perms, 453 win_inheritance=win_inheritance, 454 win_perms_reset=win_perms_reset, 455 **kwargs 456 ) 457 458 459def managed( 460 name, 461 template_name=None, 462 template_source=None, 463 template_hash=None, 464 template_hash_name=None, 465 saltenv="base", 466 template_engine="jinja", 467 skip_verify=False, 468 context=None, 469 defaults=None, 470 test=False, 471 commit=True, 472 debug=False, 473 replace=False, 474 commit_in=None, 475 commit_at=None, 476 revert_in=None, 477 revert_at=None, 478 **template_vars 479): 480 """ 481 Manages the configuration on network devices. 482 483 By default this state will commit the changes on the device. If there are no changes required, it does not commit 484 and the field ``already_configured`` from the output dictionary will be set as ``True`` to notify that. 485 486 To avoid committing the configuration, set the argument ``test`` to ``True`` (or via the CLI argument ``test=True``) 487 and will discard (dry run). 488 489 To preserve the changes, set ``commit`` to ``False`` (either as CLI argument, either as state parameter). 490 However, this is recommended to be used only in exceptional cases when there are applied few consecutive states 491 and/or configuration changes. Otherwise the user might forget that the config DB is locked and the candidate config 492 buffer is not cleared/merged in the running config. 493 494 To replace the config, set ``replace`` to ``True``. This option is recommended to be used with caution! 495 496 template_name 497 Identifies path to the template source. The template can be either stored on the local machine, 498 either remotely. 499 The recommended location is under the ``file_roots`` as specified in the master config file. 500 For example, let's suppose the ``file_roots`` is configured as: 501 502 .. code-block:: yaml 503 504 file_roots: 505 base: 506 - /etc/salt/states 507 508 Placing the template under ``/etc/salt/states/templates/example.jinja``, it can be used as 509 ``salt://templates/example.jinja``. 510 Alternatively, for local files, the user can specify the absolute path. 511 If remotely, the source can be retrieved via ``http``, ``https`` or ``ftp``. 512 513 Examples: 514 515 - ``salt://my_template.jinja`` 516 - ``/absolute/path/to/my_template.jinja`` 517 - ``http://example.com/template.cheetah`` 518 - ``https:/example.com/template.mako`` 519 - ``ftp://example.com/template.py`` 520 521 .. versionchanged:: 2019.2.0 522 This argument can now support a list of templates to be rendered. 523 The resulting configuration text is loaded at once, as a single 524 configuration chunk. 525 526 template_source: None 527 Inline config template to be rendered and loaded on the device. 528 529 template_hash: None 530 Hash of the template file. Format: ``{hash_type: 'md5', 'hsum': <md5sum>}`` 531 532 template_hash_name: None 533 When ``template_hash`` refers to a remote file, this specifies the filename to look for in that file. 534 535 saltenv: base 536 Specifies the template environment. This will influence the relative imports inside the templates. 537 538 template_engine: jinja 539 The following templates engines are supported: 540 541 - :mod:`cheetah<salt.renderers.cheetah>` 542 - :mod:`genshi<salt.renderers.genshi>` 543 - :mod:`jinja<salt.renderers.jinja>` 544 - :mod:`mako<salt.renderers.mako>` 545 - :mod:`py<salt.renderers.py>` 546 - :mod:`wempy<salt.renderers.wempy>` 547 548 skip_verify: False 549 If ``True``, hash verification of remote file sources (``http://``, ``https://``, ``ftp://``) will be skipped, 550 and the ``source_hash`` argument will be ignored. 551 552 .. versionchanged:: 2017.7.1 553 554 test: False 555 Dry run? If set to ``True``, will apply the config, discard and return the changes. Default: ``False`` 556 (will commit the changes on the device). 557 558 commit: True 559 Commit? Default: ``True``. 560 561 debug: False 562 Debug mode. Will insert a new key under the output dictionary, as ``loaded_config`` containing the raw 563 result after the template was rendered. 564 565 .. note:: 566 This argument cannot be used directly on the command line. Instead, 567 it can be passed through the ``pillar`` variable when executing 568 either of the :py:func:`state.sls <salt.modules.state.sls>` or 569 :py:func:`state.apply <salt.modules.state.apply>` (see below for an 570 example). 571 572 commit_in: ``None`` 573 Commit the changes in a specific number of minutes / hours. Example of 574 accepted formats: ``5`` (commit in 5 minutes), ``2m`` (commit in 2 575 minutes), ``1h`` (commit the changes in 1 hour)`, ``5h30m`` (commit 576 the changes in 5 hours and 30 minutes). 577 578 .. note:: 579 This feature works on any platforms, as it does not rely on the 580 native features of the network operating system. 581 582 .. note:: 583 After the command is executed and the ``diff`` is not satisfactory, 584 or for any other reasons you have to discard the commit, you are 585 able to do so using the 586 :py:func:`net.cancel_commit <salt.modules.napalm_network.cancel_commit>` 587 execution function, using the commit ID returned by this function. 588 589 .. warning:: 590 Using this feature, Salt will load the exact configuration you 591 expect, however the diff may change in time (i.e., if an user 592 applies a manual configuration change, or a different process or 593 command changes the configuration in the meanwhile). 594 595 .. versionadded:: 2019.2.0 596 597 commit_at: ``None`` 598 Commit the changes at a specific time. Example of accepted formats: 599 ``1am`` (will commit the changes at the next 1AM), ``13:20`` (will 600 commit at 13:20), ``1:20am``, etc. 601 602 .. note:: 603 This feature works on any platforms, as it does not rely on the 604 native features of the network operating system. 605 606 .. note:: 607 After the command is executed and the ``diff`` is not satisfactory, 608 or for any other reasons you have to discard the commit, you are 609 able to do so using the 610 :py:func:`net.cancel_commit <salt.modules.napalm_network.cancel_commit>` 611 execution function, using the commit ID returned by this function. 612 613 .. warning:: 614 Using this feature, Salt will load the exact configuration you 615 expect, however the diff may change in time (i.e., if an user 616 applies a manual configuration change, or a different process or 617 command changes the configuration in the meanwhile). 618 619 .. versionadded:: 2019.2.0 620 621 revert_in: ``None`` 622 Commit and revert the changes in a specific number of minutes / hours. 623 Example of accepted formats: ``5`` (revert in 5 minutes), ``2m`` (revert 624 in 2 minutes), ``1h`` (revert the changes in 1 hour)`, ``5h30m`` (revert 625 the changes in 5 hours and 30 minutes). 626 627 .. note:: 628 To confirm the commit, and prevent reverting the changes, you will 629 have to execute the 630 :mod:`net.confirm_commit <salt.modules.napalm_network.confirm_commit>` 631 function, using the commit ID returned by this function. 632 633 .. warning:: 634 This works on any platform, regardless if they have or don't have 635 native capabilities to confirming a commit. However, please be 636 *very* cautious when using this feature: on Junos (as it is the only 637 NAPALM core platform supporting this natively) it executes a commit 638 confirmed as you would do from the command line. 639 All the other platforms don't have this capability natively, 640 therefore the revert is done via Salt. That means, your device needs 641 to be reachable at the moment when Salt will attempt to revert your 642 changes. Be cautious when pushing configuration changes that would 643 prevent you reach the device. 644 645 Similarly, if an user or a different process apply other 646 configuration changes in the meanwhile (between the moment you 647 commit and till the changes are reverted), these changes would be 648 equally reverted, as Salt cannot be aware of them. 649 650 .. versionadded:: 2019.2.0 651 652 revert_at: ``None`` 653 Commit and revert the changes at a specific time. Example of accepted 654 formats: ``1am`` (will commit and revert the changes at the next 1AM), 655 ``13:20`` (will commit and revert at 13:20), ``1:20am``, etc. 656 657 .. note:: 658 To confirm the commit, and prevent reverting the changes, you will 659 have to execute the 660 :mod:`net.confirm_commit <salt.modules.napalm_network.confirm_commit>` 661 function, using the commit ID returned by this function. 662 663 .. warning:: 664 This works on any platform, regardless if they have or don't have 665 native capabilities to confirming a commit. However, please be 666 *very* cautious when using this feature: on Junos (as it is the only 667 NAPALM core platform supporting this natively) it executes a commit 668 confirmed as you would do from the command line. 669 All the other platforms don't have this capability natively, 670 therefore the revert is done via Salt. That means, your device needs 671 to be reachable at the moment when Salt will attempt to revert your 672 changes. Be cautious when pushing configuration changes that would 673 prevent you reach the device. 674 675 Similarly, if an user or a different process apply other 676 configuration changes in the meanwhile (between the moment you 677 commit and till the changes are reverted), these changes would be 678 equally reverted, as Salt cannot be aware of them. 679 680 .. versionadded:: 2019.2.0 681 682 replace: False 683 Load and replace the configuration. Default: ``False`` (will apply load merge). 684 685 context: None 686 Overrides default context variables passed to the template. 687 688 .. versionadded:: 2019.2.0 689 690 defaults: None 691 Default variables/context passed to the template. 692 693 template_vars 694 Dictionary with the arguments/context to be used when the template is rendered. Do not explicitly specify this 695 argument. This represents any other variable that will be sent to the template rendering system. Please 696 see an example below! In both ``ntp_peers_example_using_pillar`` and ``ntp_peers_example``, ``peers`` is sent as 697 template variable. 698 699 .. note:: 700 It is more recommended to use the ``context`` argument instead, to 701 avoid any conflicts with other arguments. 702 703 SLS Example (e.g.: under salt://router/config.sls) : 704 705 .. code-block:: yaml 706 707 whole_config_example: 708 netconfig.managed: 709 - template_name: salt://path/to/complete_config.jinja 710 - debug: True 711 - replace: True 712 bgp_config_example: 713 netconfig.managed: 714 - template_name: /absolute/path/to/bgp_neighbors.mako 715 - template_engine: mako 716 prefix_lists_example: 717 netconfig.managed: 718 - template_name: prefix_lists.cheetah 719 - debug: True 720 - template_engine: cheetah 721 ntp_peers_example: 722 netconfig.managed: 723 - template_name: http://bit.ly/2gKOj20 724 - skip_verify: False 725 - debug: True 726 - peers: 727 - 192.168.0.1 728 - 192.168.0.1 729 ntp_peers_example_using_pillar: 730 netconfig.managed: 731 - template_name: http://bit.ly/2gKOj20 732 - peers: {{ pillar.get('ntp.peers', []) }} 733 734 Multi template example: 735 736 .. code-block:: yaml 737 738 hostname_and_ntp: 739 netconfig.managed: 740 - template_name: 741 - https://bit.ly/2OhSgqP 742 - https://bit.ly/2M6C4Lx 743 - https://bit.ly/2OIWVTs 744 - debug: true 745 - context: 746 hostname: {{ opts.id }} 747 servers: 748 - 172.17.17.1 749 - 172.17.17.2 750 peers: 751 - 192.168.0.1 752 - 192.168.0.2 753 754 Usage examples: 755 756 .. code-block:: bash 757 758 $ sudo salt 'juniper.device' state.sls router.config test=True 759 760 $ sudo salt -N all-routers state.sls router.config pillar="{'debug': True}" 761 762 ``router.config`` depends on the location of the SLS file (see above). Running this command, will be executed all 763 five steps from above. These examples above are not meant to be used in a production environment, their sole purpose 764 is to provide usage examples. 765 766 Output example: 767 768 .. code-block:: bash 769 770 $ sudo salt 'juniper.device' state.sls router.config test=True 771 juniper.device: 772 ---------- 773 ID: ntp_peers_example_using_pillar 774 Function: netconfig.managed 775 Result: None 776 Comment: Testing mode: Configuration discarded. 777 Started: 12:01:40.744535 778 Duration: 8755.788 ms 779 Changes: 780 ---------- 781 diff: 782 [edit system ntp] 783 peer 192.168.0.1 { ... } 784 + peer 172.17.17.1; 785 + peer 172.17.17.3; 786 787 Summary for juniper.device 788 ------------ 789 Succeeded: 1 (unchanged=1, changed=1) 790 Failed: 0 791 ------------ 792 Total states run: 1 793 Total run time: 8.756 s 794 795 Raw output example (useful when the output is reused in other states/execution modules): 796 797 .. code-block:: bash 798 799 $ sudo salt --out=pprint 'juniper.device' state.sls router.config test=True debug=True 800 801 .. code-block:: python 802 803 { 804 'juniper.device': { 805 'netconfig_|-ntp_peers_example_using_pillar_|-ntp_peers_example_using_pillar_|-managed': { 806 '__id__': 'ntp_peers_example_using_pillar', 807 '__run_num__': 0, 808 'already_configured': False, 809 'changes': { 810 'diff': '[edit system ntp] peer 192.168.0.1 { ... }+ peer 172.17.17.1;+ peer 172.17.17.3;' 811 }, 812 'comment': 'Testing mode: Configuration discarded.', 813 'duration': 7400.759, 814 'loaded_config': 'system { ntp { peer 172.17.17.1; peer 172.17.17.3; } }', 815 'name': 'ntp_peers_example_using_pillar', 816 'result': None, 817 'start_time': '12:09:09.811445' 818 } 819 } 820 } 821 """ 822 ret = salt.utils.napalm.default_ret(name) 823 824 # the user can override the flags the equivalent CLI args 825 # which have higher precedence 826 test = test or __opts__["test"] 827 debug = __salt__["config.merge"]("debug", debug) 828 commit = __salt__["config.merge"]("commit", commit) 829 replace = __salt__["config.merge"]("replace", replace) # this might be a bit risky 830 skip_verify = __salt__["config.merge"]("skip_verify", skip_verify) 831 commit_in = __salt__["config.merge"]("commit_in", commit_in) 832 commit_at = __salt__["config.merge"]("commit_at", commit_at) 833 revert_in = __salt__["config.merge"]("revert_in", revert_in) 834 revert_at = __salt__["config.merge"]("revert_at", revert_at) 835 836 config_update_ret = _update_config( 837 template_name=template_name, 838 template_source=template_source, 839 template_hash=template_hash, 840 template_hash_name=template_hash_name, 841 saltenv=saltenv, 842 template_engine=template_engine, 843 skip_verify=skip_verify, 844 context=context, 845 defaults=defaults, 846 test=test, 847 commit=commit, 848 commit_in=commit_in, 849 commit_at=commit_at, 850 revert_in=revert_in, 851 revert_at=revert_at, 852 debug=debug, 853 replace=replace, 854 **template_vars 855 ) 856 857 return salt.utils.napalm.loaded_ret(ret, config_update_ret, test, debug) 858 859 860def commit_cancelled(name): 861 """ 862 .. versionadded:: 2019.2.0 863 864 Cancel a commit scheduled to be executed via the ``commit_in`` and 865 ``commit_at`` arguments from the 866 :py:func:`net.load_template <salt.modules.napalm_network.load_template>` or 867 :py:func:`net.load_config <salt.modules.napalm_network.load_config>` 868 execution functions. The commit ID is displayed when the commit is scheduled 869 via the functions named above. 870 871 State SLS Example: 872 873 .. code-block:: yaml 874 875 '20180726083540640360': 876 netconfig.commit_cancelled 877 """ 878 cancelled = {"name": name, "result": None, "changes": {}, "comment": ""} 879 if __opts__["test"]: 880 cancelled["comment"] = "It would cancel commit #{}".format(name) 881 return cancelled 882 ret = __salt__["net.cancel_commit"](name) 883 cancelled.update(ret) 884 return cancelled 885 886 887def commit_confirmed(name): 888 """ 889 .. versionadded:: 2019.2.0 890 891 Confirm a commit scheduled to be reverted via the ``revert_in`` and 892 ``revert_at`` arguments from the 893 :mod:`net.load_template <salt.modules.napalm_network.load_template>` or 894 :mod:`net.load_config <salt.modules.napalm_network.load_config>` 895 execution functions. The commit ID is displayed when the commit confirmed 896 is scheduled via the functions named above. 897 898 State SLS Example: 899 900 .. code-block:: yaml 901 902 '20180726083540640360': 903 netconfig.commit_confirmed 904 """ 905 confirmed = {"name": name, "result": None, "changes": {}, "comment": ""} 906 if __opts__["test"]: 907 confirmed["comment"] = "It would confirm commit #{}".format(name) 908 return confirmed 909 ret = __salt__["net.confirm_commit"](name) 910 confirmed.update(ret) 911 return confirmed 912