├── .flake8 ├── .github └── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md ├── .gitignore ├── .travis.yml ├── CHANGELOG.md ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── Dockerfile ├── Dockerfile.dev ├── LICENSE.md ├── MANIFEST.in ├── Makefile ├── PULL_REQUEST_TEMPLATE.md ├── Pipfile ├── ProjectProposal.md ├── README.md ├── RELEASE.md ├── ROADMAP.md ├── ansible_kernel ├── __init__.py ├── __main__.py ├── convert_playbook.py ├── exporters │ ├── __init__.py │ ├── ansible_playbook.py │ ├── ansible_tasks.py │ └── ansible_zip.py ├── install.py ├── kernel.py ├── module_args.py ├── module_args.yml ├── modules.py ├── modules.yml ├── play_args.py ├── plugins │ ├── __init__.py │ └── callback │ │ ├── __init__.py │ │ └── ansible_kernel_helper.py ├── roles │ ├── __init__.py │ └── ansible_kernel_helpers │ │ ├── __init__.py │ │ ├── action_plugins │ │ ├── __init__.py │ │ └── pause_for_kernel.py │ │ └── library │ │ ├── __init__.py │ │ └── pause_for_kernel.py ├── task_args.py ├── templates │ ├── ansible_playbook.tpl │ └── ansible_tasks.tpl ├── update_module_cache.py └── widgets.py ├── docs ├── ansible_jupyter_kernel_vimeo.png └── example_session.png ├── notebooks ├── HelloWorld.ipynb ├── HelloWorldAnsibleJupyterWigets.ipynb ├── HelloWorldDocumentation.ipynb ├── HelloWorldGalaxyRole.ipynb ├── HelloWorldGalaxyRole2.ipynb ├── HelloWorldIncludeRole.ipynb ├── HelloWorldJupyterTools.ipynb ├── HelloWorldPlaybook.ipynb ├── HelloWorldPlaybookWithInventory.ipynb ├── HelloWorldPlaybookWithInventoryAndAnsibleCfg.ipynb ├── HelloWorldPlaybookWithTemplate.ipynb ├── HelloWorldPlaybookWithVarsFile.ipynb ├── HelloWorldPython.ipynb ├── HelloWorldPythonVariables.ipynb ├── HelloWorldRoles.ipynb ├── HelloWorldVault.ipynb ├── roles │ └── hello │ │ ├── meta │ │ └── main.yml │ │ └── tasks │ │ └── main.yml ├── templates │ └── hello.j2 └── vyos_backup.ipynb ├── openshift ├── Dockerfile ├── Dockerfile.centos ├── README.md ├── bin │ ├── run │ └── uid_entrypoint └── openshift-template.yaml ├── setup.cfg ├── setup.py └── tests ├── AllUnreachable.ipynb ├── AllUnreachableDebugOnly.ipynb ├── BadArguments.ipynb ├── DefaultInventoryExport.ipynb ├── EmptyInventory.ipynb ├── EmptyPlay.ipynb ├── EmptyTask.ipynb ├── ExportAnsibleRegisteredVariables.ipynb ├── ExportPythonVariables.ipynb ├── GalaxyRole.ipynb ├── GalaxyRole2.ipynb ├── GalaxyRole3.ipynb ├── HelloWorld.ipynb ├── MissingArgumentColon.ipynb ├── MissingColon.ipynb ├── NoHostsPlay.ipynb ├── NoNamePlay.ipynb ├── UnknownModule.ipynb └── Unreachable.ipynb /.flake8: -------------------------------------------------------------------------------- 1 | [flake8] 2 | ignore = E402 3 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | 5 | --- 6 | 7 | **Describe the bug** 8 | A clear and concise description of what the bug is. 9 | 10 | **To Reproduce** 11 | Steps to reproduce the behavior: 12 | 1. Go to '...' 13 | 2. Click on '....' 14 | 3. Scroll down to '....' 15 | 4. See error 16 | 17 | **Expected behavior** 18 | A clear and concise description of what you expected to happen. 19 | 20 | **Screenshots** 21 | If applicable, add screenshots to help explain your problem. 22 | 23 | **Desktop (please complete the following information):** 24 | - OS: [e.g. iOS] 25 | - Browser [e.g. chrome, safari] 26 | - Version [e.g. 22] 27 | - Jupyter Notebook Version 28 | - Jupyter Lab Version (if used) 29 | - Jupyter Hub Version (if used) 30 | 31 | **Smartphone (please complete the following information):** 32 | - Device: [e.g. iPhone6] 33 | - OS: [e.g. iOS8.1] 34 | - Browser [e.g. stock browser, safari] 35 | - Version [e.g. 22] 36 | 37 | **Additional context** 38 | Add any other context about the problem here. 39 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | 5 | --- 6 | 7 | **Is your feature request related to a problem? Please describe.** 8 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 9 | 10 | **Describe the solution you'd like** 11 | A clear and concise description of what you want to happen. 12 | 13 | **Describe alternatives you've considered** 14 | A clear and concise description of any alternative solutions or features you've considered. 15 | 16 | **Additional context** 17 | Add any other context or screenshots about the feature request here. 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Mac OS X 2 | *.DS_Store 3 | 4 | # Editors 5 | *.sw[poj] 6 | *~ 7 | 8 | /.tox 9 | /dist 10 | /build 11 | /*.egg-info 12 | *.py[c,o] 13 | .pytest_cache 14 | 15 | # Ansible Jupyter Kernel 16 | .ipynb_checkpoints 17 | ansible_kernel.log 18 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: python 2 | python: 3 | - "2.7" 4 | - "3.5" 5 | - "3.6" 6 | install: 7 | - pip install -e . 8 | - pip install flake8 9 | script: 10 | - flake8 . 11 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | ## [1.0.0] - 2020-02-11 4 | 5 | ### Fixes 6 | 7 | - Updates kernel to new API 8 | - AttributeError for user\_ns on AnsibleKernel 9 | - Corrects manifest 10 | - Pyyaml load deprecation 11 | 12 | ### Added 13 | 14 | - Adds support for runner\_on\_start events 15 | 16 | 17 | ## [0.9.0] - 2018-12-12 18 | 19 | ### Added 20 | 21 | - Python cell support 22 | - ipywidgets support from Ansible cells 23 | - Shared variables between Python and Ansible cells 24 | - Custom Ansible widget modules for Jupyter Notebook/Lab 25 | 26 | ## [0.8.0] - 2018-08-17 27 | 28 | 29 | ### Added 30 | 31 | - Support for #vault_password cells 32 | - Support for #python cells with access to registered variables 33 | - Support for ipywidgets from #python cells and #task cells 34 | - Support for rendering HTML from ansible modules that return `text/html` 35 | 36 | ### Changed 37 | 38 | - Use ansible-runner to manage ansible-playbook calls 39 | 40 | ### Fixes 41 | 42 | - Issue where kernel needed to be restarted after a play context is lost 43 | and could not be restarted. 44 | 45 | ## [0.7.0] - 2018-07-31 46 | 47 | ### Added 48 | 49 | - Inclusion of the default inventory in Ansible zip bundles 50 | 51 | ### Fixes 52 | 53 | - Export of Ansible zip bundles in Python 3 54 | 55 | ## [0.6.0] - 2018-07-16 56 | 57 | ### Added 58 | 59 | - Ansible playbook to Jupyter notebook format converter 60 | - Export a notebook to an Ansible bundle zip file containing the playbook, inventory, etc 61 | 62 | ## [0.5.0] - 2018-07-10 63 | 64 | ### Fixes 65 | 66 | - Python 3: Multiple fixes for package names that have changed 67 | - Python 3: String to/from byte conversions. 68 | 69 | ### Changed 70 | 71 | - Improves shell output display 72 | 73 | ## [0.4.2] - 2018-07-09 74 | 75 | ### Fixes 76 | 77 | - Kernel crash when ansible-playbook shuts down. 78 | 79 | ## [0.4.1] - 2018-07-08 80 | 81 | ### Fixes 82 | 83 | - Fixed connection to localhost to use local connection type 84 | 85 | ### Added 86 | 87 | - Dockerfile 88 | 89 | ## [0.4] - 2018-07-05 90 | 91 | ### Fixes 92 | - Python 3: Encodes unicode messages for ZMQ properly 93 | 94 | ### Added 95 | - Module argument cache 96 | - Role support 97 | - Automatic Ansible Galaxy role installation 98 | 99 | ## [0.3] - 2018-06-28 100 | ### Fixes 101 | - Fixed packaging 102 | 103 | ## [0.2] - 2018-06-28 104 | ### Added 105 | - Export notebook to Ansible playbook 106 | - Export notebook to Ansible tasks file 107 | - Error handling in play and task cells 108 | - Feedback for syntax errors in play and task cells 109 | 110 | 111 | ## [0.1] - 2018-06-27 112 | ### Added 113 | - Basic support for ansible tasks in Jupyter notebooks 114 | - Command completion support for modules, module args, and play args 115 | - Support for inventory cells 116 | - Support for task cells 117 | - Support for play cells 118 | - Support for group var cells 119 | - Support for host var cells 120 | - Support for vars file cells 121 | - Support for template cells 122 | - Support for ansible.cfg cell 123 | - Support for ansible vault in vars file cells 124 | 125 | 126 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation. 6 | 7 | ## Our Standards 8 | 9 | Examples of behavior that contributes to creating a positive environment include: 10 | 11 | * Using welcoming and inclusive language 12 | * Being respectful of differing viewpoints and experiences 13 | * Gracefully accepting constructive criticism 14 | * Focusing on what is best for the community 15 | * Showing empathy towards other community members 16 | 17 | Examples of unacceptable behavior by participants include: 18 | 19 | * The use of sexualized language or imagery and unwelcome sexual attention or advances 20 | * Trolling, insulting/derogatory comments, and personal or political attacks 21 | * Public or private harassment 22 | * Publishing others' private information, such as a physical or electronic address, without explicit permission 23 | * Other conduct which could reasonably be considered inappropriate in a professional setting 24 | 25 | ## Our Responsibilities 26 | 27 | Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. 28 | 29 | Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. 30 | 31 | ## Scope 32 | 33 | This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. 34 | 35 | ## Enforcement 36 | 37 | Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at ben.thomasson@redhat.com. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. 38 | 39 | Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. 40 | 41 | ## Attribution 42 | 43 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version] 44 | 45 | [homepage]: http://contributor-covenant.org 46 | [version]: http://contributor-covenant.org/version/1/4/ 47 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to Ansible Jupyter Kernel 2 | We love your input! We want to make contributing to this project as easy and transparent as possible, whether it's: 3 | 4 | - Reporting a bug 5 | - Discussing the current state of the code 6 | - Submitting a fix 7 | - Proposing new features 8 | - Becoming a maintainer 9 | 10 | ## We Develop with Github 11 | We use github to host code, to track issues and feature requests, as well as accept pull requests. 12 | 13 | ## We Use [Github Flow](https://guides.github.com/introduction/flow/index.html), So All Code Changes Happen Through Pull Requests 14 | Pull requests are the best way to propose changes to the codebase (we use [Github Flow](https://guides.github.com/introduction/flow/index.html)). We actively welcome your pull requests: 15 | 16 | 1. Fork the repo and create your branch from `master`. 17 | 2. If you've added code that should be tested, add tests. 18 | 3. If you've changed APIs, update the documentation. 19 | 4. Ensure the test suite passes. 20 | 5. Make sure your code lints. 21 | 6. Issue that pull request! 22 | 23 | ## Any contributions you make will be under the Apache 2.0 Software License 24 | In short, when you submit code changes, your submissions are understood to be under the same [Apache 2.0 License](http://choosealicense.com/licenses/apache-2.0/) that covers the project. Feel free to contact the maintainers if that's a concern. 25 | 26 | ## Report bugs using Github's [issues](https://github.com/ansible/ansible-jupyter-kernel/issues) 27 | We use GitHub issues to track public bugs. Report a bug by [opening a new issue](https://github.com/ansible/ansible-jupyter-kernel/issues/new); it's that easy! 28 | 29 | ## Write bug reports with detail, background, and sample code 30 | 31 | **Great Bug Reports** tend to have: 32 | 33 | - A quick summary and/or background 34 | - Steps to reproduce 35 | - Be specific! 36 | - Give sample code if you can. 37 | - What you expected would happen 38 | - What actually happens 39 | - Notes (possibly including why you think this might be happening, or stuff you tried that didn't work) 40 | 41 | People *love* thorough bug reports. I'm not even kidding. 42 | 43 | ## Use a Consistent Coding Style 44 | 45 | * 4 spaces for indentation rather than tabs 46 | * Run flake8 on your changes to check for consistent style 47 | 48 | ## License 49 | By contributing, you agree that your contributions will be licensed under its Apache 2.0 License. 50 | 51 | ## References 52 | This document was adapted from the open-source contribution guidelines for [Facebook's Draft](https://github.com/facebook/draft-js/blob/a9316a723f9e918afde44dea68b5f9f39b7d9b00/CONTRIBUTING.md) 53 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM fedora:29 2 | 3 | # Install Ansible Jupyter Kernel 4 | RUN dnf install -y python2-ipykernel python2-jupyter-core gcc python2-devel \ 5 | bzip2 openssh openssh-clients python2-crypto python2-psutil glibc-locale-source && \ 6 | localedef -c -i en_US -f UTF-8 en_US.UTF-8 && \ 7 | pip install --no-cache-dir wheel psutil && \ 8 | rm -rf /var/cache/yum 9 | 10 | ENV LANG=en_US.UTF-8 \ 11 | LANGUAGE=en_US:en \ 12 | LC_ALL=en_US.UTF-8 13 | 14 | ENV NB_USER notebook 15 | ENV NB_UID 1000 16 | ENV HOME /home/${NB_USER} 17 | 18 | RUN useradd \ 19 | -c "Default user" \ 20 | -d /home/notebook \ 21 | -u ${NB_UID} \ 22 | ${NB_USER} 23 | 24 | COPY . ${HOME} 25 | USER root 26 | RUN chown -R ${NB_UID} ${HOME} 27 | 28 | RUN pip install --no-cache-dir ansible-jupyter-widgets 29 | RUN pip install --no-cache-dir ansible_kernel==1.0.0 && \ 30 | python -m ansible_kernel.install 31 | USER ${NB_USER} 32 | WORKDIR /home/notebook/notebooks 33 | CMD ["jupyter-notebook", "--ip", "0.0.0.0"] 34 | EXPOSE 8888 35 | -------------------------------------------------------------------------------- /Dockerfile.dev: -------------------------------------------------------------------------------- 1 | FROM fedora:29 2 | 3 | # Install Ansible Jupyter Kernel 4 | RUN dnf install -y python2-ipykernel python2-jupyter-core gcc python2-devel \ 5 | bzip2 openssh openssh-clients python2-crypto python2-psutil glibc-locale-source && \ 6 | localedef -c -i en_US -f UTF-8 en_US.UTF-8 && \ 7 | pip install --no-cache-dir wheel psutil && \ 8 | rm -rf /var/cache/yum 9 | 10 | ENV LANG=en_US.UTF-8 \ 11 | LANGUAGE=en_US:en \ 12 | LC_ALL=en_US.UTF-8 13 | 14 | ENV NB_USER notebook 15 | ENV NB_UID 1000 16 | ENV HOME /home/${NB_USER} 17 | 18 | RUN useradd \ 19 | -c "Default user" \ 20 | -d /home/notebook \ 21 | -u ${NB_UID} \ 22 | ${NB_USER} 23 | 24 | COPY . ${HOME} 25 | USER root 26 | RUN chown -R ${NB_UID} ${HOME} 27 | 28 | ADD dist/ansible_kernel-1.0.0-py2.py3-none-any.whl /ansible_kernel-1.0.0-py2.py3-none-any.whl 29 | 30 | RUN pip install --no-cache-dir ansible-jupyter-widgets 31 | RUN pip install --no-cache-dir /ansible_kernel-1.0.0-py2.py3-none-any.whl && \ 32 | python -m ansible_kernel.install 33 | USER ${NB_USER} 34 | WORKDIR /home/notebook/notebooks 35 | CMD ["jupyter-notebook", "--ip", "0.0.0.0"] 36 | EXPOSE 8888 37 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | Apache License 2 | ============== 3 | 4 | _Version 2.0, January 2004_ 5 | _<>_ 6 | 7 | ### Terms and Conditions for use, reproduction, and distribution 8 | 9 | #### 1. Definitions 10 | 11 | “License” shall mean the terms and conditions for use, reproduction, and 12 | distribution as defined by Sections 1 through 9 of this document. 13 | 14 | “Licensor” shall mean the copyright owner or entity authorized by the copyright 15 | owner that is granting the License. 16 | 17 | “Legal Entity” shall mean the union of the acting entity and all other entities 18 | that control, are controlled by, or are under common control with that entity. 19 | For the purposes of this definition, “control” means **(i)** the power, direct or 20 | indirect, to cause the direction or management of such entity, whether by 21 | contract or otherwise, or **(ii)** ownership of fifty percent (50%) or more of the 22 | outstanding shares, or **(iii)** beneficial ownership of such entity. 23 | 24 | “You” (or “Your”) shall mean an individual or Legal Entity exercising 25 | permissions granted by this License. 26 | 27 | “Source” form shall mean the preferred form for making modifications, including 28 | but not limited to software source code, documentation source, and configuration 29 | files. 30 | 31 | “Object” form shall mean any form resulting from mechanical transformation or 32 | translation of a Source form, including but not limited to compiled object code, 33 | generated documentation, and conversions to other media types. 34 | 35 | “Work” shall mean the work of authorship, whether in Source or Object form, made 36 | available under the License, as indicated by a copyright notice that is included 37 | in or attached to the work (an example is provided in the Appendix below). 38 | 39 | “Derivative Works” shall mean any work, whether in Source or Object form, that 40 | is based on (or derived from) the Work and for which the editorial revisions, 41 | annotations, elaborations, or other modifications represent, as a whole, an 42 | original work of authorship. For the purposes of this License, Derivative Works 43 | shall not include works that remain separable from, or merely link (or bind by 44 | name) to the interfaces of, the Work and Derivative Works thereof. 45 | 46 | “Contribution” shall mean any work of authorship, including the original version 47 | of the Work and any modifications or additions to that Work or Derivative Works 48 | thereof, that is intentionally submitted to Licensor for inclusion in the Work 49 | by the copyright owner or by an individual or Legal Entity authorized to submit 50 | on behalf of the copyright owner. For the purposes of this definition, 51 | “submitted” means any form of electronic, verbal, or written communication sent 52 | to the Licensor or its representatives, including but not limited to 53 | communication on electronic mailing lists, source code control systems, and 54 | issue tracking systems that are managed by, or on behalf of, the Licensor for 55 | the purpose of discussing and improving the Work, but excluding communication 56 | that is conspicuously marked or otherwise designated in writing by the copyright 57 | owner as “Not a Contribution.” 58 | 59 | “Contributor” shall mean Licensor and any individual or Legal Entity on behalf 60 | of whom a Contribution has been received by Licensor and subsequently 61 | incorporated within the Work. 62 | 63 | #### 2. Grant of Copyright License 64 | 65 | Subject to the terms and conditions of this License, each Contributor hereby 66 | grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, 67 | irrevocable copyright license to reproduce, prepare Derivative Works of, 68 | publicly display, publicly perform, sublicense, and distribute the Work and such 69 | Derivative Works in Source or Object form. 70 | 71 | #### 3. Grant of Patent License 72 | 73 | Subject to the terms and conditions of this License, each Contributor hereby 74 | grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, 75 | irrevocable (except as stated in this section) patent license to make, have 76 | made, use, offer to sell, sell, import, and otherwise transfer the Work, where 77 | such license applies only to those patent claims licensable by such Contributor 78 | that are necessarily infringed by their Contribution(s) alone or by combination 79 | of their Contribution(s) with the Work to which such Contribution(s) was 80 | submitted. If You institute patent litigation against any entity (including a 81 | cross-claim or counterclaim in a lawsuit) alleging that the Work or a 82 | Contribution incorporated within the Work constitutes direct or contributory 83 | patent infringement, then any patent licenses granted to You under this License 84 | for that Work shall terminate as of the date such litigation is filed. 85 | 86 | #### 4. Redistribution 87 | 88 | You may reproduce and distribute copies of the Work or Derivative Works thereof 89 | in any medium, with or without modifications, and in Source or Object form, 90 | provided that You meet the following conditions: 91 | 92 | * **(a)** You must give any other recipients of the Work or Derivative Works a copy of 93 | this License; and 94 | * **(b)** You must cause any modified files to carry prominent notices stating that You 95 | changed the files; and 96 | * **(c)** You must retain, in the Source form of any Derivative Works that You distribute, 97 | all copyright, patent, trademark, and attribution notices from the Source form 98 | of the Work, excluding those notices that do not pertain to any part of the 99 | Derivative Works; and 100 | * **(d)** If the Work includes a “NOTICE” text file as part of its distribution, then any 101 | Derivative Works that You distribute must include a readable copy of the 102 | attribution notices contained within such NOTICE file, excluding those notices 103 | that do not pertain to any part of the Derivative Works, in at least one of the 104 | following places: within a NOTICE text file distributed as part of the 105 | Derivative Works; within the Source form or documentation, if provided along 106 | with the Derivative Works; or, within a display generated by the Derivative 107 | Works, if and wherever such third-party notices normally appear. The contents of 108 | the NOTICE file are for informational purposes only and do not modify the 109 | License. You may add Your own attribution notices within Derivative Works that 110 | You distribute, alongside or as an addendum to the NOTICE text from the Work, 111 | provided that such additional attribution notices cannot be construed as 112 | modifying the License. 113 | 114 | You may add Your own copyright statement to Your modifications and may provide 115 | additional or different license terms and conditions for use, reproduction, or 116 | distribution of Your modifications, or for any such Derivative Works as a whole, 117 | provided Your use, reproduction, and distribution of the Work otherwise complies 118 | with the conditions stated in this License. 119 | 120 | #### 5. Submission of Contributions 121 | 122 | Unless You explicitly state otherwise, any Contribution intentionally submitted 123 | for inclusion in the Work by You to the Licensor shall be under the terms and 124 | conditions of this License, without any additional terms or conditions. 125 | Notwithstanding the above, nothing herein shall supersede or modify the terms of 126 | any separate license agreement you may have executed with Licensor regarding 127 | such Contributions. 128 | 129 | #### 6. Trademarks 130 | 131 | This License does not grant permission to use the trade names, trademarks, 132 | service marks, or product names of the Licensor, except as required for 133 | reasonable and customary use in describing the origin of the Work and 134 | reproducing the content of the NOTICE file. 135 | 136 | #### 7. Disclaimer of Warranty 137 | 138 | Unless required by applicable law or agreed to in writing, Licensor provides the 139 | Work (and each Contributor provides its Contributions) on an “AS IS” BASIS, 140 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, 141 | including, without limitation, any warranties or conditions of TITLE, 142 | NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are 143 | solely responsible for determining the appropriateness of using or 144 | redistributing the Work and assume any risks associated with Your exercise of 145 | permissions under this License. 146 | 147 | #### 8. Limitation of Liability 148 | 149 | In no event and under no legal theory, whether in tort (including negligence), 150 | contract, or otherwise, unless required by applicable law (such as deliberate 151 | and grossly negligent acts) or agreed to in writing, shall any Contributor be 152 | liable to You for damages, including any direct, indirect, special, incidental, 153 | or consequential damages of any character arising as a result of this License or 154 | out of the use or inability to use the Work (including but not limited to 155 | damages for loss of goodwill, work stoppage, computer failure or malfunction, or 156 | any and all other commercial damages or losses), even if such Contributor has 157 | been advised of the possibility of such damages. 158 | 159 | #### 9. Accepting Warranty or Additional Liability 160 | 161 | While redistributing the Work or Derivative Works thereof, You may choose to 162 | offer, and charge a fee for, acceptance of support, warranty, indemnity, or 163 | other liability obligations and/or rights consistent with this License. However, 164 | in accepting such obligations, You may act only on Your own behalf and on Your 165 | sole responsibility, not on behalf of any other Contributor, and only if You 166 | agree to indemnify, defend, and hold each Contributor harmless for any liability 167 | incurred by, or claims asserted against, such Contributor by reason of your 168 | accepting any such warranty or additional liability. 169 | -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | include LICENSE.md 2 | include ansible_kernel/templates/*.tpl 3 | include ansible_kernel/*.yml 4 | recursive-include ansible_kernel/roles *.py 5 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | PYTHON ?= python 2 | ifeq ($(origin VIRTUAL_ENV),undefined) 3 | DIST_PYTHON ?= pipenv run $(PYTHON) 4 | else 5 | DIST_PYTHON ?= $(PYTHON) 6 | endif 7 | 8 | NAME = ansible-runner 9 | IMAGE_NAME ?= $(NAME) 10 | PIP_NAME = ansible_runner 11 | VERSION = $(shell $(DIST_PYTHON) setup.py --version) 12 | 13 | .PHONY: clean dist sdist dev shell 14 | 15 | clean: 16 | rm -rf dist 17 | 18 | dist: 19 | $(DIST_PYTHON) setup.py bdist_wheel --universal 20 | 21 | sdist: dist/$(PIP_NAME)-$(VERSION).tar.gz 22 | 23 | dist/$(PIP_NAME)-$(VERSION).tar.gz: 24 | $(DIST_PYTHON) setup.py sdist 25 | 26 | dev: 27 | pipenv install 28 | 29 | shell: 30 | pipenv shell 31 | 32 | docker: 33 | docker build -t benthomasson/ansible-jupyter-kernel:latest . 34 | 35 | docker-dev: dist 36 | docker build -t benthomasson/ansible-jupyter-kernel:dev -f Dockerfile.dev . 37 | 38 | docker-run: 39 | docker run -it -p 8888:8888 benthomasson/ansible-jupyter-kernel:latest 40 | 41 | docker-run-dev: 42 | docker run -it -p 8888:8888 benthomasson/ansible-jupyter-kernel:dev 43 | -------------------------------------------------------------------------------- /PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | ## Status 2 | **READY/WIP** 3 | 4 | ## Description 5 | A few sentences describing the overall goals of the pull request's commits. 6 | 7 | ## Related PRs 8 | List related PRs against other branches: 9 | 10 | branch | PR 11 | ------ | ------ 12 | other_pr_production | [link]() 13 | other_pr_master | [link]() 14 | 15 | 16 | ## Todos 17 | - [ ] Tests 18 | - [ ] Documentation 19 | 20 | ## Impacted Areas in Application 21 | List general components of the application that this PR will affect: 22 | 23 | -------------------------------------------------------------------------------- /Pipfile: -------------------------------------------------------------------------------- 1 | [[source]] 2 | url = "https://pypi.org/simple" 3 | verify_ssl = true 4 | name = "pypi" 5 | 6 | [packages] 7 | pyyaml = ">=4.2b1" 8 | jupyter = "*" 9 | notebook = ">=5.7.2" 10 | pyzmq = "*" 11 | tornado = "*" 12 | jupyter-nbextensions-configurator = "*" 13 | ansible = "*" 14 | singledispatch = "*" 15 | pytest = "*" 16 | backports-abc = "*" 17 | defusedxml = "*" 18 | ansible-runner = "*" 19 | ipywidgets = "*" 20 | cryptography = ">=2.3" 21 | paramiko = ">=2.4.2" 22 | 23 | [dev-packages] 24 | -------------------------------------------------------------------------------- /ProjectProposal.md: -------------------------------------------------------------------------------- 1 | 2 | Project: Jupyter Notebook as a Playbook Builder 3 | =============================================== 4 | 5 | Problem 6 | ------- 7 | 8 | Getting started with Ansible requires an understanding of the Linux command line shells. 9 | Network engineers may be new to Linux command line shells and this will reduce the 10 | number of customers and/or increase how long it will take for them to get started. 11 | 12 | Solution 13 | -------- 14 | 15 | Provide a way to build playbooks interactively and to debug interactively by 16 | using a Jupyter Notebook style interface with ansible play cells and 17 | ansible task cells. This web interface could be provided with AWX/Tower 18 | to remove the need to understand Linux for playbook developers. 19 | 20 | 21 | Pitch Concept and Demo to interested parties 22 | -------------------------------------------- 23 | 24 | Jupyter notebook + ansible cell type = web-based ansible playbook builder 25 | 26 | 27 | Reactions 28 | --------- 29 | 30 | * [Fri June 8th 10:46 AM] matburt: :open_mouth: :mind-blown.gif: 31 | * [Tue Jun 12 12:41:09 EDT 2018] chrismeyers: that'd be hot. patent that. 32 | * [Tue Jun 12 15:44:31 EDT 2018] matburt :open_mouth: wowsa how do I get this hotness? 33 | * [Wed Jun 13 2018] docschick: You've earned your brownies. 34 | * [Jun 27 2018] @rrrrrrrix: holy shit 35 | * [July 9th 2018 10:45 AM ] shanemcd: i love this btw. i’ve always wanted something like it. 36 | 37 | 38 | Jupyter Notebook Technical Details 39 | ---------------------------------- 40 | 41 | * Front end javascript 42 | * Back end python 43 | * Back end is split up into many projects/repositories 44 | + https://github.com/jupyter/notebook 45 | + https://github.com/ipython/ipykernel 46 | + https://github.com/jupyter/jupyter_core 47 | + https://github.com/jupyter/jupyter_client 48 | + https://github.com/jupyter/nbformat 49 | + https://github.com/jupyter/nbconvert 50 | 51 | * Depends on tornado for event loop 52 | * Depends on ZMQ for messaging 53 | * Client-server communication is via a REST API + a web socket. 54 | + See: https://github.com/jupyter/jupyter/wiki/Jupyter-Notebook-Server-API 55 | 56 | * There are already many kernels for other languages: 57 | + https://github.com/jupyter/jupyter/wiki/Jupyter-kernels 58 | + http://jupyter-client.readthedocs.io/en/latest/kernels.html 59 | 60 | * Kernels are very easy to write with the given base class that handles messaging. 61 | + See: https://github.com/ipython/ipykernel/blob/master/ipykernel/kernelbase.py 62 | 63 | 64 | Road Map 65 | ======== 66 | 67 | 68 | Initial Project Evaluation 69 | --------------------------- 70 | * Time: 2 days (100% done) 71 | * 1 resource: 1 architect 72 | * Result: this document 73 | 74 | 75 | Prototype 76 | --------- 77 | * Time: 1 week (100% done) 78 | * 1 resource: Python/Javascript 79 | * Result: Run contents of a notebook cell as a task in an Ansible playbook and 80 | display output of after it finishes on the notebook. 81 | 82 | Tasks: 83 | 84 | - Add ansible kernel that keeps a play context running. See ipython/ipykernel for an example of a kernel. (done) 85 | - Add tab completion for ansible modules (done) 86 | - Add tab completion for ansible module arguments (done) 87 | - Add documentation integration (done) 88 | - Add export to playbook (done) 89 | - Rewrite a few of the Ansible for Networks tutorials with this 90 | 91 | 92 | Release 0 Beta (Early Access) 93 | ----------------------------- 94 | * Time: 3 weeks 95 | * 2 resources: 1 python, 1 tester, +community 96 | * Result: Improve prototype to a useful point and release as a stand-alone module 97 | for use the Juypter notebooks and add to AWX. 98 | 99 | Tasks: 100 | 101 | - Legal license approval (done) 102 | - Release manager approval (done) 103 | - Add to public repo under ansible (done) 104 | - Add all the standard python packaging files (done) 105 | - Push module to PYPI (done) 106 | - Push container to dockerhub (done) 107 | - Add awx integration 108 | - Test by converting tutorials to notebooks 109 | - Write blog post 110 | - Write AnsibleFest talk (submitted talk) 111 | - Demo recordings 112 | 113 | 114 | Release 1 Product 115 | ------------------------------------ 116 | * Time: 3 months work 117 | * 4 resources: 1 python, 1 javascript, 1 designer, 1 tester 118 | * Result: A product useful for building ansible playbooks 119 | 120 | Tasks: 121 | 122 | - Playbook importing 123 | - Change branding to Tower with Jupyter 124 | - Integrate with Tower 125 | - Add RBAC 126 | - Add integration with projects 127 | - Add integration with inventories 128 | 129 | Result: A web based UI that can build simple playbooks consisting of tasks 130 | 131 | 132 | Release 2 Product 133 | ------------------------------------ 134 | * Time: 3 months work 135 | * 5 resources: 1 python, 2 javascript, 1 designer, 1 tester 136 | * Result: A product for useful for building and editing most playbooks 137 | 138 | Tasks: 139 | 140 | - Complete conversion of Jupyter Notebook to Ansible Playook builder 141 | 142 | Release 3 Product 143 | ------------------------------------ 144 | * Time: 3 months work 145 | * 4 resources: 1 python, 1 javascript, 1 designer, 1 tester 146 | * Result: A web based UI that can build most playbooks and roles 147 | 148 | Tasks: 149 | 150 | - Add features for building roles 151 | 152 | 153 | Release 4 Product 154 | ------------------------------------ 155 | * Time: 3 months work 156 | * 5 resources: 1 python, 2 javascript, 1 designer, 1 tester 157 | * Result: A web based UI that can build most playbooks, roles, and modules 158 | 159 | Tasks: 160 | 161 | - Add features for building modules 162 | 163 | Risks 164 | ----- 165 | 166 | - Jupyter has a BSD license with modifications. 167 | - Many repositories would need vendoring or repackage into one repository 168 | - Managing upstream changes from a project with many changes. 169 | - Managing community reactions to a Jupyter notebook fork. 170 | - Adding new dependencies to production Tower 171 | - We may have to add an Ansible kernel for each version of Ansible that we want to support. 172 | 173 | Risk Mitigation 174 | --------------- 175 | 176 | - Very few modifications to Juypter repos are needed to support Ansible as a kernel. 177 | (only changes to nbconvert were needed for exporting playbooks) 178 | - Jupyter Notebook is already used in AWX development for debug/management of django. 179 | - Jupyter Notebook is architected in multiple repositories which allows for plugging 180 | in code to support ansible fairly easily. 181 | - BSD licensed projects can be re-licensed 182 | - Vendoring Jupyter source into Tower should be easy enough. Although upstream patches would have to be applied manually. 183 | - The Ansible kernel could be a part of core to reduce cost of maintaining the strict version requirements for future releases. 184 | 185 | Proposal Review 186 | --------------- 187 | 188 | * This is hot 189 | * This is cool 190 | * Does this have a git workflow? No. 191 | * How many ansible users would this use this feature? About 50%. 192 | * It's probably more for new users than power users. 193 | * It might be useful for power users. 194 | * Integration with Ansible Runner would be useful for both projects. 195 | * Integration with Tower may come at a later date. 196 | * Release as an OS community project. 197 | 198 | 199 | Blog and Talk Ideas 200 | ------------------- 201 | 202 | * Ansible Playbook builder using Jupyter and Ansible Kernel for the Ansible community 203 | * Setting up AWS with Ansible and Jupyter targeting the Jupyter community 204 | 205 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Ansible Jupyter Kernel 2 | 3 | [![Build Status](https://travis-ci.com/ansible/ansible-jupyter-kernel.svg?branch=master)](https://travis-ci.com/ansible/ansible-jupyter-kernel) 4 | [![Binder](https://mybinder.org/badge.svg)](https://mybinder.org/v2/gh/ansible/ansible-jupyter-kernel/master) 5 | 6 | 7 | 8 | ![Example Jupyter Usage](https://raw.githubusercontent.com/ansible/ansible-jupyter-kernel/master/docs/example_session.png) 9 | 10 | The Ansible [Jupyter](http://jupyter.readthedocs.io/en/latest/) Kernel adds a kernel backend for Jupyter to interface directly with Ansible and construct plays and tasks and execute them on the fly. 11 | 12 | ## Demo 13 | 14 | [![Demo](https://raw.githubusercontent.com/ansible/ansible-jupyter-kernel/master/docs/ansible_jupyter_kernel_vimeo.png)](https://vimeo.com/279049946 "Run Ansible Tasks from Jupyter Notebook - Click to Watch!") 15 | 16 | 17 | ## Table of Contents 18 | 19 | * [Installation](#installation) 20 | * [From pypi](#from-pypi) 21 | * [From a local checkout](#from-a-local-checkout) 22 | * [Usage](#usage) 23 | * [Using the cells](#using-the-cells) 24 | * [Examples](#examples) 25 | * [Using the development environment](#using-the-development-environment) 26 | 27 | ## Installation: 28 | 29 | `ansible-kernel` is available to be installed from pypi but you can also install it locally. The setup package itself will register the kernel 30 | with `Jupyter` automatically. 31 | 32 | ### From pypi 33 | 34 | pip install ansible-kernel 35 | python -m ansible_kernel.install 36 | 37 | ### From a local checkout 38 | 39 | pip install -e . 40 | python -m ansible_kernel.install 41 | 42 | ### For Anaconda/Miniconda 43 | 44 | pip install ansible-kernel 45 | python -m ansible_kernel.install --sys-prefix 46 | 47 | ## Usage 48 | 49 | ### Local install 50 | 51 | ``` 52 | jupyter notebook 53 | # In the notebook interface, select Ansible from the 'New' menu 54 | ``` 55 | 56 | ### Container 57 | 58 | docker run -p 8888:8888 benthomasson/ansible-jupyter-kernel 59 | 60 | Then copy the URL from the output into your browser: 61 | http://localhost:8888/?token=ABCD1234 62 | 63 | 64 | ## Using the Cells 65 | 66 | Normally `Ansible` brings together various components in different files and locations to launch a playbook and performs automation tasks. For this 67 | `jupyter` interface you need to provide this information in cells by denoting what the cell contains and then finally writing your tasks that will make 68 | use of them. There are [Examples](#examples) available to help you, in this section we'll go over the currently supported cell types. 69 | 70 | In order to denote what the cell contains you should prefix it with a pound/hash symbol (#) and the type as listed here as the first line as shown in the examples 71 | below. 72 | 73 | #### #inventory 74 | 75 | The inventory that your tasks will use 76 | 77 | ``` 78 | #inventory 79 | [all] 80 | ahost ansible_connection=local 81 | anotherhost examplevar=val 82 | ``` 83 | 84 | #### #play 85 | 86 | This represents the opening block of a typical `Ansible` play 87 | 88 | ``` 89 | #play 90 | name: Hello World 91 | hosts: all 92 | gather_facts: false 93 | ``` 94 | 95 | #### #task 96 | 97 | This is the default cell type if no type is given for the first line 98 | 99 | ``` 100 | #task 101 | debug: 102 | ``` 103 | 104 | ``` 105 | #task 106 | shell: cat /tmp/afile 107 | register: output 108 | ``` 109 | 110 | #### #host_vars 111 | 112 | This takes an argument that represents the hostname. Variables 113 | defined in this file will be available in the tasks for that host. 114 | 115 | ``` 116 | #host_vars Host1 117 | hostname: host1 118 | ``` 119 | 120 | #### #group_vars 121 | 122 | This takes an argument that represents the group name. Variables 123 | defined in this file will be available in the tasks for hosts in that 124 | group. 125 | 126 | ``` 127 | #group_vars BranchOfficeX 128 | gateway: 192.168.1.254 129 | ``` 130 | 131 | #### #vars 132 | 133 | This takes an argument that represents the filename for use in later cells 134 | 135 | ``` 136 | #vars example_vars 137 | message: hello vars 138 | ``` 139 | 140 | ``` 141 | #play 142 | name: hello world 143 | hosts: localhost 144 | gather_facts: false 145 | vars_files: 146 | - example_vars 147 | ``` 148 | 149 | #### #template 150 | 151 | This takes an argument in order to create a templated file that can be used in later cells 152 | 153 | ``` 154 | #template hello.j2 155 | {{ message }} 156 | ``` 157 | 158 | ``` 159 | #task 160 | template: 161 | src: hello.j2 162 | dest: /tmp/hello 163 | ``` 164 | 165 | #### #ansible.cfg 166 | 167 | Provides overrides typically found in ansible.cfg 168 | 169 | ``` 170 | #ansible.cfg 171 | [defaults] 172 | host_key_checking=False 173 | ``` 174 | 175 | ### Examples 176 | 177 | You can find various [example notebooks in the repository](https://github.com/ansible/ansible-jupyter-kernel/tree/master/notebooks) 178 | 179 | ## Using the development environment 180 | 181 | It's possible to use whatever python development process you feel comfortable with. The repository itself includes mechanisms for 182 | using [pipenv](https://github.com/pypa/pipenv) 183 | 184 | ``` 185 | pipenv install 186 | ... 187 | pipenv shell 188 | ``` 189 | -------------------------------------------------------------------------------- /RELEASE.md: -------------------------------------------------------------------------------- 1 | 2 | # Ansible Jupyter Kernel Release Process 3 | 4 | 5 | - Create release branch with format `release_{version}` 6 | - Update CHANGELOG.md 7 | - Update ROADMAP.md 8 | - Update version in setup.py, ansible_kernel/kernel.py, Dockerfile 9 | - Create pull request for the release 10 | - Run `make dist sdist` 11 | - Run `make docker-dev` 12 | - Run `make docker-run-dev` 13 | - Run all notebooks as tests in Jupyter notebook UI 14 | - Run `twine upload dist/*` 15 | - Check that the version uploaded to pypi at https://pypi.org/project/ansible-kernel/#history 16 | - Run `make docker` 17 | - Run `docker build -t benthomasson/ansible-jupyter-kernel:{version} .` 18 | - Run `docker push benthomasson/ansible-jupyter-kernel:{version}` 19 | - Merge pull request 20 | - Run `git pull upstream master` 21 | - Run `git tag -a {version}` with comment {version} 22 | - Run `git push --tags upstream` 23 | - Done 24 | 25 | -------------------------------------------------------------------------------- /ROADMAP.md: -------------------------------------------------------------------------------- 1 | # Roadmap 2 | 3 | ## [0.10.0] 4 | 5 | ### Add 6 | 7 | - HTML Play Summary 8 | 9 | -------------------------------------------------------------------------------- /ansible_kernel/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ansible/ansible-jupyter-kernel/09efa5d4073a72d1d56cce60574c743a1feb1954/ansible_kernel/__init__.py -------------------------------------------------------------------------------- /ansible_kernel/__main__.py: -------------------------------------------------------------------------------- 1 | import logging 2 | FORMAT = "[%(asctime)s] %(levelname)s [%(name)s.%(funcName)s:%(lineno)d] %(message)s" 3 | logging.basicConfig(filename='ansible_kernel.log', level=logging.DEBUG, format=FORMAT) # noqa 4 | from ipykernel.kernelapp import IPKernelApp 5 | from .kernel import AnsibleKernel 6 | IPKernelApp.launch_instance(kernel_class=AnsibleKernel) 7 | -------------------------------------------------------------------------------- /ansible_kernel/convert_playbook.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | Usage: 6 | convert_playbook [options] [] [(--vars-file )]... [(--template-file )]... 7 | 8 | Options: 9 | -h, --help Show this page 10 | --debug Show debug logging 11 | --verbose Show verbose logging 12 | --ansible-cfg= 13 | --inventory= 14 | --host-vars-files-dir= 15 | --group-vars-files-dir= 16 | --templates-dir= 17 | --vars-files-dir= 18 | """ 19 | from docopt import docopt 20 | import logging 21 | import sys 22 | import yaml 23 | import json 24 | import os 25 | import glob 26 | import functools 27 | 28 | NB_FORMAT = 4 29 | NB_FORMAT_MINOR = 2 30 | METADATA = json.loads('''{ 31 | "kernelspec": { 32 | "display_name": "Ansible", 33 | "language": "ansible", 34 | "name": "ansible" 35 | }, 36 | "language_info": { 37 | "codemirror_mode": "yaml", 38 | "file_extension": ".yml", 39 | "mimetype": "text/yaml", 40 | "name": "ansible" 41 | } 42 | }''') 43 | 44 | logger = logging.getLogger('convert_playbook') 45 | 46 | 47 | yaml_dump = functools.partial(yaml.safe_dump, default_flow_style=False) 48 | json_dump = functools.partial(json.dumps, indent=4, sort_keys=True, separators=(',', ': ')) 49 | 50 | 51 | def main(args=None): 52 | if args is None: 53 | args = sys.argv[1:] 54 | parsed_args = docopt(__doc__, args) 55 | if parsed_args['--debug']: 56 | logging.basicConfig(level=logging.DEBUG) 57 | elif parsed_args['--verbose']: 58 | logging.basicConfig(level=logging.INFO) 59 | else: 60 | logging.basicConfig(level=logging.WARNING) 61 | 62 | playbook_file = os.path.abspath(parsed_args['']) 63 | ansible_cfg = parsed_args['--ansible-cfg'] 64 | inventory = parsed_args['--inventory'] 65 | templates_dir = parsed_args['--templates-dir'] 66 | vars_files_dir = parsed_args['--vars-files-dir'] 67 | group_vars_files_dir = parsed_args['--group-vars-files-dir'] 68 | host_vars_files_dir = parsed_args['--host-vars-files-dir'] 69 | vars_files = parsed_args[''] 70 | template_files = parsed_args[''] 71 | print(parsed_args) 72 | if not os.path.exists(playbook_file): 73 | print("No playbook file found at {0}".format(playbook_file)) 74 | return 1 75 | 76 | if ansible_cfg is not None: 77 | ansible_cfg = os.path.abspath(ansible_cfg) 78 | if not os.path.exists(ansible_cfg): 79 | print("No ansible.cfg file found at {0}".format(ansible_cfg)) 80 | return 1 81 | 82 | if inventory is not None: 83 | inventory = os.path.abspath(inventory) 84 | if not os.path.exists(inventory): 85 | print("No inventory file found at {0}".format(inventory)) 86 | return 1 87 | 88 | if templates_dir is not None: 89 | if not os.path.exists(templates_dir): 90 | print("No templates directory found at {0}".format(templates_dir)) 91 | return 1 92 | 93 | if vars_files_dir is not None: 94 | if not os.path.exists(vars_files_dir): 95 | print("No vars files directory found at {0}".format(vars_files_dir)) 96 | return 1 97 | 98 | if host_vars_files_dir is not None: 99 | if not os.path.exists(host_vars_files_dir): 100 | print("No host vars directory found at {0}".format(host_vars_files_dir)) 101 | return 1 102 | 103 | if group_vars_files_dir is not None: 104 | if not os.path.exists(group_vars_files_dir): 105 | print("No group vars directory found at {0}".format(group_vars_files_dir)) 106 | return 1 107 | if vars_files is not None: 108 | for vars_file in vars_files: 109 | if not os.path.exists(vars_file): 110 | print("No vars file found at {0}".format(vars_file)) 111 | return 1 112 | if template_files is not None: 113 | for template_file in template_files: 114 | if not os.path.exists(template_file): 115 | print("No template file found at {0}".format(vars_file)) 116 | return 1 117 | 118 | if parsed_args[''] is not None: 119 | output_file = os.path.abspath(parsed_args['']) 120 | else: 121 | base_name, _ = os.path.splitext(playbook_file) 122 | output_file = os.path.abspath(base_name + ".ipynb") 123 | 124 | with open(playbook_file) as f: 125 | content = f.read() 126 | plays = yaml.load(content, Loader=yaml.FullLoader) 127 | 128 | cells = [] 129 | 130 | def add_code_cell(cell_type, code): 131 | source = "#{0}\n{1}".format(cell_type, code) 132 | new_cell = dict(cell_type="code", 133 | metadata={}, 134 | execution_count=None, 135 | outputs=[], 136 | source=source.splitlines(True)) 137 | print(new_cell) 138 | cells.append(new_cell) 139 | 140 | if ansible_cfg is not None: 141 | with open(ansible_cfg) as f: 142 | add_code_cell('ansible.cfg', f.read()) 143 | 144 | if inventory is not None: 145 | with open(inventory) as f: 146 | add_code_cell('inventory', f.read()) 147 | 148 | if templates_dir is not None: 149 | for template in glob.glob(templates_dir, '*'): 150 | with open(template) as f: 151 | add_code_cell('template {0}'.format(template), f.read()) 152 | 153 | if template_files is not None: 154 | for template_file in template_files: 155 | with open(template_file) as f: 156 | add_code_cell('template_file {0}'.format(template_file), f.read()) 157 | 158 | if vars_files_dir is not None: 159 | for vars_file in glob.glob(vars_files_dir, '*'): 160 | with open(vars_file) as f: 161 | add_code_cell('vars_file {0}'.format(vars_file), f.read()) 162 | 163 | if vars_files is not None: 164 | for vars_file in vars_files: 165 | with open(vars_file) as f: 166 | add_code_cell('vars_file {0}'.format(vars_file), f.read()) 167 | 168 | if group_vars_files_dir is not None: 169 | for group_vars in glob.glob(group_vars_files_dir, '*'): 170 | with open(group_vars) as f: 171 | add_code_cell('group_vars {0}'.format(group_vars), f.read()) 172 | 173 | if host_vars_files_dir is not None: 174 | for host_vars in glob.glob(host_vars_files_dir, '*'): 175 | with open(host_vars) as f: 176 | add_code_cell('host_vars {0}'.format(host_vars), f.read()) 177 | 178 | for play in plays: 179 | play_copy = play.copy() 180 | if 'tasks' in play_copy: 181 | del play_copy['tasks'] 182 | add_code_cell('play', yaml_dump(play_copy)) 183 | for task in play.get('tasks', []): 184 | add_code_cell('task', yaml_dump(task)) 185 | 186 | with open(output_file, 'w') as f: 187 | f.write(json_dump(dict(cells=cells, 188 | metadata=METADATA, 189 | nbformat=NB_FORMAT, 190 | nbformat_minor=NB_FORMAT_MINOR))) 191 | 192 | return 0 193 | 194 | 195 | if __name__ == '__main__': 196 | sys.exit(main(sys.argv[1:])) 197 | -------------------------------------------------------------------------------- /ansible_kernel/exporters/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | from .ansible_tasks import AnsibleTasksExporter # noqa 3 | from .ansible_playbook import AnsiblePlaybookExporter # noqa 4 | from .ansible_zip import AnsibleZipExporter # noqa 5 | -------------------------------------------------------------------------------- /ansible_kernel/exporters/ansible_playbook.py: -------------------------------------------------------------------------------- 1 | """Ansible Playbook Exporter class""" 2 | 3 | import os 4 | 5 | from traitlets import default 6 | 7 | from nbconvert.exporters.templateexporter import TemplateExporter 8 | 9 | 10 | class AnsiblePlaybookExporter(TemplateExporter): 11 | """ 12 | Exports an Ansible Playbook file. 13 | """ 14 | 15 | export_from_notebook = 'Ansible Playbook' 16 | output_mimetype = 'text/yml' 17 | 18 | @default('file_extension') 19 | def _file_extension_default(self): 20 | return '.yml' 21 | 22 | @default('template_file') 23 | def _template_file_default(self): 24 | return 'ansible_playbook.tpl' 25 | 26 | @property 27 | def template_path(self): 28 | return super(AnsiblePlaybookExporter, self).template_path + [os.path.join(os.path.dirname(os.path.dirname(__file__)), "templates")] 29 | -------------------------------------------------------------------------------- /ansible_kernel/exporters/ansible_tasks.py: -------------------------------------------------------------------------------- 1 | """Ansible tasks Exporter class""" 2 | 3 | import os 4 | 5 | from traitlets import default 6 | 7 | from nbconvert.exporters.templateexporter import TemplateExporter 8 | 9 | 10 | class AnsibleTasksExporter(TemplateExporter): 11 | """ 12 | Exports an Ansible tasks file. 13 | """ 14 | 15 | export_from_notebook = "Ansible Tasks" 16 | output_mimetype = 'text/yml' 17 | 18 | @default('file_extension') 19 | def _file_extension_default(self): 20 | return '.yaml' 21 | 22 | @default('template_file') 23 | def _template_file_default(self): 24 | return 'ansible_tasks.tpl' 25 | 26 | @property 27 | def template_path(self): 28 | return super(AnsibleTasksExporter, self).template_path + [os.path.join(os.path.dirname(os.path.dirname(__file__)), "templates")] 29 | -------------------------------------------------------------------------------- /ansible_kernel/exporters/ansible_zip.py: -------------------------------------------------------------------------------- 1 | """Ansible Playbook Exporter class""" 2 | 3 | import six 4 | import zipfile 5 | 6 | from traitlets import default 7 | 8 | from nbconvert.exporters.exporter import Exporter 9 | from .ansible_playbook import AnsiblePlaybookExporter 10 | 11 | 12 | DEFAULT_INVENTORY = '[all]\nlocalhost ansible_connection=local' 13 | 14 | 15 | class AnsibleZipExporter(Exporter): 16 | """ 17 | Exports an Ansible Bundle file. 18 | """ 19 | 20 | export_from_notebook = 'Ansible Zip Bundle' 21 | output_mimetype = 'application/zip' 22 | 23 | @default('file_extension') 24 | def _file_extension_default(self): 25 | return '.zip' 26 | 27 | def from_notebook_node(self, nb, resources=None, **kw): 28 | nb_copy, resources = super(AnsibleZipExporter, self).from_notebook_node(nb, resources, **kw) 29 | 30 | resources_copy = resources.copy() 31 | 32 | contents = six.BytesIO() 33 | 34 | playbook_exporter = AnsiblePlaybookExporter() 35 | playbook, _ = playbook_exporter.from_notebook_node(nb, resources_copy, **kw) 36 | inventory = DEFAULT_INVENTORY 37 | ansible_cfg = None 38 | templates = [] 39 | vars_files = [] 40 | host_vars = [] 41 | group_vars = [] 42 | 43 | def get_file_name(source, prefix): 44 | return source[0][len(prefix):].strip() 45 | 46 | for cell in nb_copy.get('cells', []): 47 | source = cell.get('source', '').strip().splitlines() 48 | if len(source) > 0: 49 | if source[0].startswith("#inventory"): 50 | inventory = '\n'.join(source[1:]) 51 | elif source[0].startswith("#ansible.cfg"): 52 | ansible_cfg = '\n'.join(source[1:]) 53 | elif source[0].startswith("#template"): 54 | file_name = get_file_name(source, '#template') 55 | templates.append((file_name, '\n'.join(source[1:]))) 56 | elif source[0].startswith("#vars"): 57 | file_name = get_file_name(source, '#vars') 58 | vars_files.append((file_name, '\n'.join(source[1:]))) 59 | elif source[0].startswith("#host_vars"): 60 | file_name = get_file_name(source, '#host_vars') 61 | host_vars.append((file_name, '\n'.join(source[1:]))) 62 | elif source[0].startswith("#group_vars"): 63 | file_name = get_file_name(source, '#group_vars') 64 | group_vars.append((file_name, '\n'.join(source[1:]))) 65 | 66 | zip_file = zipfile.ZipFile(contents, "a", zipfile.ZIP_DEFLATED, False) 67 | if ansible_cfg is not None: 68 | zip_file.writestr('ansible.cfg', ansible_cfg) 69 | 70 | zip_file.writestr('inventory', inventory) 71 | 72 | for template in templates: 73 | zip_file.writestr(*template) 74 | for vars_file in vars_files: 75 | zip_file.writestr(*vars_file) 76 | for host_vars_file in host_vars: 77 | zip_file.writestr(*host_vars_file) 78 | for group_vars_file in group_vars: 79 | zip_file.writestr(*group_vars_file) 80 | zip_file.writestr("playbook.yml", playbook) 81 | zip_file.close() 82 | 83 | output = contents.getvalue() 84 | 85 | return output, resources 86 | -------------------------------------------------------------------------------- /ansible_kernel/install.py: -------------------------------------------------------------------------------- 1 | import json 2 | import os 3 | import sys 4 | import argparse 5 | 6 | from jupyter_client.kernelspec import KernelSpecManager 7 | from IPython.utils.tempdir import TemporaryDirectory 8 | 9 | kernel_json = {"argv": [sys.executable, "-m", "ansible_kernel", "-f", "{connection_file}"], 10 | "display_name": "Ansible", 11 | "language": "ansible", 12 | "codemirror_mode": "yaml", 13 | "env": {"PS1": "$"} 14 | } 15 | 16 | 17 | def install_my_kernel_spec(user=True, prefix=None): 18 | with TemporaryDirectory() as td: 19 | os.chmod(td, 0o755) # Starts off as 700, not user readable 20 | with open(os.path.join(td, 'kernel.json'), 'w') as f: 21 | json.dump(kernel_json, f, sort_keys=True) 22 | # TODO: Copy resources once they're specified 23 | 24 | print('Installing IPython kernel spec') 25 | KernelSpecManager().install_kernel_spec( 26 | td, 'ansible', user=user, replace=True, prefix=prefix) 27 | 28 | 29 | def _is_root(): 30 | try: 31 | return os.geteuid() == 0 32 | except AttributeError: 33 | return False # assume not an admin on non-Unix platforms 34 | 35 | 36 | def main(argv=None): 37 | parser = argparse.ArgumentParser( 38 | description='Install KernelSpec for Ansible Kernel' 39 | ) 40 | prefix_locations = parser.add_mutually_exclusive_group() 41 | 42 | prefix_locations.add_argument( 43 | '--user', 44 | help='Install KernelSpec in user homedirectory', 45 | action='store_true' 46 | ) 47 | prefix_locations.add_argument( 48 | '--sys-prefix', 49 | help='Install KernelSpec in sys.prefix. Useful in conda / virtualenv', 50 | action='store_true', 51 | dest='sys_prefix' 52 | ) 53 | prefix_locations.add_argument( 54 | '--prefix', 55 | help='Install KernelSpec in this prefix', 56 | default=None 57 | ) 58 | 59 | args = parser.parse_args(argv) 60 | 61 | user = False 62 | prefix = None 63 | if args.sys_prefix: 64 | prefix = sys.prefix 65 | elif args.prefix: 66 | prefix = args.prefix 67 | elif args.user or not _is_root(): 68 | user = True 69 | 70 | install_my_kernel_spec(user=user, prefix=prefix) 71 | 72 | 73 | if __name__ == '__main__': 74 | main() 75 | -------------------------------------------------------------------------------- /ansible_kernel/module_args.py: -------------------------------------------------------------------------------- 1 | import pkg_resources 2 | import yaml 3 | with open(pkg_resources.resource_filename('ansible_kernel', 'module_args.yml')) as f: 4 | module_args = yaml.load(f.read(), Loader=yaml.FullLoader) 5 | module_args = module_args 6 | -------------------------------------------------------------------------------- /ansible_kernel/modules.py: -------------------------------------------------------------------------------- 1 | import pkg_resources 2 | import yaml 3 | with open(pkg_resources.resource_filename('ansible_kernel', 'modules.yml')) as f: 4 | modules = yaml.load(f.read(), Loader=yaml.FullLoader) 5 | modules = modules 6 | -------------------------------------------------------------------------------- /ansible_kernel/modules.yml: -------------------------------------------------------------------------------- 1 | - a10_server 2 | - a10_server_axapi3 3 | - a10_service_group 4 | - a10_virtual_server 5 | - accelerate 6 | - aci_aaa_user 7 | - aci_aaa_user_certificate 8 | - aci_access_port_to_interface_policy_leaf_profile 9 | - aci_aep 10 | - aci_aep_to_domain 11 | - aci_ap 12 | - aci_bd 13 | - aci_bd_subnet 14 | - aci_bd_to_l3out 15 | - aci_config_rollback 16 | - aci_config_snapshot 17 | - aci_contract 18 | - aci_contract_subject 19 | - aci_contract_subject_to_filter 20 | - aci_domain 21 | - aci_domain_to_encap_pool 22 | - aci_domain_to_vlan_pool 23 | - aci_encap_pool 24 | - aci_encap_pool_range 25 | - aci_epg 26 | - aci_epg_monitoring_policy 27 | - aci_epg_to_contract 28 | - aci_epg_to_domain 29 | - aci_fabric_node 30 | - aci_filter 31 | - aci_filter_entry 32 | - aci_firmware_source 33 | - aci_interface_policy_fc 34 | - aci_interface_policy_l2 35 | - aci_interface_policy_leaf_policy_group 36 | - aci_interface_policy_leaf_profile 37 | - aci_interface_policy_lldp 38 | - aci_interface_policy_mcp 39 | - aci_interface_policy_port_channel 40 | - aci_interface_policy_port_security 41 | - aci_interface_selector_to_switch_policy_leaf_profile 42 | - aci_intf_policy_fc 43 | - aci_intf_policy_l2 44 | - aci_intf_policy_lldp 45 | - aci_intf_policy_mcp 46 | - aci_intf_policy_port_channel 47 | - aci_intf_policy_port_security 48 | - aci_l3out 49 | - aci_l3out_route_tag_policy 50 | - aci_rest 51 | - aci_static_binding_to_epg 52 | - aci_switch_leaf_selector 53 | - aci_switch_policy_leaf_profile 54 | - aci_switch_policy_vpc_protection_group 55 | - aci_taboo_contract 56 | - aci_tenant 57 | - aci_tenant_action_rule_profile 58 | - aci_tenant_ep_retention_policy 59 | - aci_tenant_span_dst_group 60 | - aci_tenant_span_src_group 61 | - aci_tenant_span_src_group_to_dst_group 62 | - aci_vlan_pool 63 | - aci_vlan_pool_encap_block 64 | - aci_vrf 65 | - acl 66 | - acme_account 67 | - acme_certificate 68 | - add_host 69 | - airbrake_deployment 70 | - aireos_command 71 | - aireos_config 72 | - aix_inittab 73 | - aix_lvol 74 | - alternatives 75 | - aos_asn_pool 76 | - aos_blueprint 77 | - aos_blueprint_param 78 | - aos_blueprint_virtnet 79 | - aos_device 80 | - aos_external_router 81 | - aos_ip_pool 82 | - aos_logical_device 83 | - aos_logical_device_map 84 | - aos_login 85 | - aos_rack_type 86 | - aos_template 87 | - apache2_mod_proxy 88 | - apache2_module 89 | - apk 90 | - apt 91 | - apt_key 92 | - apt_repository 93 | - apt_rpm 94 | - archive 95 | - aruba_command 96 | - aruba_config 97 | - asa_acl 98 | - asa_command 99 | - asa_config 100 | - assemble 101 | - assert 102 | - async_status 103 | - at 104 | - atomic_container 105 | - atomic_host 106 | - atomic_image 107 | - authorized_key 108 | - avi_actiongroupconfig 109 | - avi_alertconfig 110 | - avi_alertemailconfig 111 | - avi_alertscriptconfig 112 | - avi_alertsyslogconfig 113 | - avi_analyticsprofile 114 | - avi_api_session 115 | - avi_api_version 116 | - avi_applicationpersistenceprofile 117 | - avi_applicationprofile 118 | - avi_authprofile 119 | - avi_autoscalelaunchconfig 120 | - avi_backup 121 | - avi_backupconfiguration 122 | - avi_certificatemanagementprofile 123 | - avi_cloud 124 | - avi_cloudconnectoruser 125 | - avi_cloudproperties 126 | - avi_cluster 127 | - avi_clusterclouddetails 128 | - avi_controllerproperties 129 | - avi_customipamdnsprofile 130 | - avi_dnspolicy 131 | - avi_errorpagebody 132 | - avi_errorpageprofile 133 | - avi_gslb 134 | - avi_gslbapplicationpersistenceprofile 135 | - avi_gslbgeodbprofile 136 | - avi_gslbhealthmonitor 137 | - avi_gslbservice 138 | - avi_gslbservice_patch_member 139 | - avi_hardwaresecuritymodulegroup 140 | - avi_healthmonitor 141 | - avi_httppolicyset 142 | - avi_ipaddrgroup 143 | - avi_ipamdnsproviderprofile 144 | - avi_l4policyset 145 | - avi_microservicegroup 146 | - avi_network 147 | - avi_networkprofile 148 | - avi_networksecuritypolicy 149 | - avi_pkiprofile 150 | - avi_pool 151 | - avi_poolgroup 152 | - avi_poolgroupdeploymentpolicy 153 | - avi_prioritylabels 154 | - avi_role 155 | - avi_scheduler 156 | - avi_seproperties 157 | - avi_serverautoscalepolicy 158 | - avi_serviceengine 159 | - avi_serviceenginegroup 160 | - avi_snmptrapprofile 161 | - avi_sslkeyandcertificate 162 | - avi_sslprofile 163 | - avi_stringgroup 164 | - avi_systemconfiguration 165 | - avi_tenant 166 | - avi_trafficcloneprofile 167 | - avi_useraccount 168 | - avi_useraccountprofile 169 | - avi_virtualservice 170 | - avi_vrfcontext 171 | - avi_vsdatascriptset 172 | - avi_vsvip 173 | - avi_wafpolicy 174 | - avi_wafprofile 175 | - avi_webhook 176 | - awall 177 | - aws_acm_facts 178 | - aws_api_gateway 179 | - aws_application_scaling_policy 180 | - aws_az_facts 181 | - aws_batch_compute_environment 182 | - aws_batch_job_definition 183 | - aws_batch_job_queue 184 | - aws_caller_facts 185 | - aws_config_aggregation_authorization 186 | - aws_config_aggregator 187 | - aws_config_delivery_channel 188 | - aws_config_recorder 189 | - aws_config_rule 190 | - aws_direct_connect_connection 191 | - aws_direct_connect_gateway 192 | - aws_direct_connect_link_aggregation_group 193 | - aws_direct_connect_virtual_interface 194 | - aws_elasticbeanstalk_app 195 | - aws_glue_connection 196 | - aws_glue_job 197 | - aws_inspector_target 198 | - aws_kms 199 | - aws_kms_facts 200 | - aws_region_facts 201 | - aws_s3 202 | - aws_s3_bucket_facts 203 | - aws_s3_cors 204 | - aws_ses_identity 205 | - aws_ses_identity_policy 206 | - aws_sgw_facts 207 | - aws_ssm_parameter_store 208 | - aws_waf_condition 209 | - aws_waf_facts 210 | - aws_waf_rule 211 | - aws_waf_web_acl 212 | - azure 213 | - azure_rm_acs 214 | - azure_rm_aks 215 | - azure_rm_aks_facts 216 | - azure_rm_availabilityset 217 | - azure_rm_availabilityset_facts 218 | - azure_rm_containerinstance 219 | - azure_rm_containerregistry 220 | - azure_rm_deployment 221 | - azure_rm_dnsrecordset 222 | - azure_rm_dnsrecordset_facts 223 | - azure_rm_dnszone 224 | - azure_rm_dnszone_facts 225 | - azure_rm_functionapp 226 | - azure_rm_functionapp_facts 227 | - azure_rm_image 228 | - azure_rm_keyvault 229 | - azure_rm_keyvaultkey 230 | - azure_rm_keyvaultsecret 231 | - azure_rm_loadbalancer 232 | - azure_rm_loadbalancer_facts 233 | - azure_rm_managed_disk 234 | - azure_rm_managed_disk_facts 235 | - azure_rm_mysqldatabase 236 | - azure_rm_mysqlserver 237 | - azure_rm_networkinterface 238 | - azure_rm_networkinterface_facts 239 | - azure_rm_postgresqldatabase 240 | - azure_rm_postgresqlserver 241 | - azure_rm_publicipaddress 242 | - azure_rm_publicipaddress_facts 243 | - azure_rm_resource 244 | - azure_rm_resource_facts 245 | - azure_rm_resourcegroup 246 | - azure_rm_resourcegroup_facts 247 | - azure_rm_securitygroup 248 | - azure_rm_securitygroup_facts 249 | - azure_rm_sqldatabase 250 | - azure_rm_sqlserver 251 | - azure_rm_sqlserver_facts 252 | - azure_rm_storageaccount 253 | - azure_rm_storageaccount_facts 254 | - azure_rm_storageblob 255 | - azure_rm_subnet 256 | - azure_rm_virtualmachine 257 | - azure_rm_virtualmachine_extension 258 | - azure_rm_virtualmachine_scaleset 259 | - azure_rm_virtualmachine_scaleset_facts 260 | - azure_rm_virtualmachineimage_facts 261 | - azure_rm_virtualnetwork 262 | - azure_rm_virtualnetwork_facts 263 | - bcf_switch 264 | - beadm 265 | - bearychat 266 | - bigip_asm_policy 267 | - bigip_command 268 | - bigip_config 269 | - bigip_configsync_action 270 | - bigip_data_group 271 | - bigip_device_connectivity 272 | - bigip_device_dns 273 | - bigip_device_group 274 | - bigip_device_group_member 275 | - bigip_device_httpd 276 | - bigip_device_license 277 | - bigip_device_ntp 278 | - bigip_device_sshd 279 | - bigip_device_trust 280 | - bigip_facts 281 | - bigip_gtm_datacenter 282 | - bigip_gtm_facts 283 | - bigip_gtm_global 284 | - bigip_gtm_monitor_bigip 285 | - bigip_gtm_monitor_external 286 | - bigip_gtm_monitor_firepass 287 | - bigip_gtm_monitor_http 288 | - bigip_gtm_monitor_https 289 | - bigip_gtm_monitor_tcp 290 | - bigip_gtm_monitor_tcp_half_open 291 | - bigip_gtm_pool 292 | - bigip_gtm_pool_member 293 | - bigip_gtm_server 294 | - bigip_gtm_virtual_server 295 | - bigip_gtm_wide_ip 296 | - bigip_hostname 297 | - bigip_iapp_service 298 | - bigip_iapp_template 299 | - bigip_iapplx_package 300 | - bigip_irule 301 | - bigip_log_destination 302 | - bigip_log_publisher 303 | - bigip_management_route 304 | - bigip_monitor_external 305 | - bigip_monitor_http 306 | - bigip_monitor_https 307 | - bigip_monitor_snmp_dca 308 | - bigip_monitor_tcp 309 | - bigip_monitor_tcp_echo 310 | - bigip_monitor_tcp_half_open 311 | - bigip_monitor_udp 312 | - bigip_node 313 | - bigip_partition 314 | - bigip_policy 315 | - bigip_policy_rule 316 | - bigip_pool 317 | - bigip_pool_member 318 | - bigip_profile_client_ssl 319 | - bigip_profile_dns 320 | - bigip_profile_tcp 321 | - bigip_profile_udp 322 | - bigip_provision 323 | - bigip_qkview 324 | - bigip_remote_syslog 325 | - bigip_routedomain 326 | - bigip_security_address_list 327 | - bigip_security_port_list 328 | - bigip_selfip 329 | - bigip_service_policy 330 | - bigip_smtp 331 | - bigip_snat_pool 332 | - bigip_snmp 333 | - bigip_snmp_community 334 | - bigip_snmp_trap 335 | - bigip_software_update 336 | - bigip_ssl_certificate 337 | - bigip_ssl_key 338 | - bigip_static_route 339 | - bigip_sys_db 340 | - bigip_sys_global 341 | - bigip_timer_policy 342 | - bigip_traffic_group 343 | - bigip_trunk 344 | - bigip_ucs 345 | - bigip_ucs_fetch 346 | - bigip_user 347 | - bigip_vcmp_guest 348 | - bigip_virtual_address 349 | - bigip_virtual_server 350 | - bigip_vlan 351 | - bigip_wait 352 | - bigiq_application_fasthttp 353 | - bigiq_application_fastl4_tcp 354 | - bigiq_application_fastl4_udp 355 | - bigiq_application_http 356 | - bigiq_application_https_offload 357 | - bigiq_application_https_waf 358 | - bigiq_regkey_license 359 | - bigiq_regkey_license_assignment 360 | - bigiq_regkey_pool 361 | - bigiq_utility_license 362 | - bigmon_chain 363 | - bigmon_policy 364 | - bigpanda 365 | - blockinfile 366 | - bower 367 | - bundler 368 | - bzr 369 | - campfire 370 | - capabilities 371 | - catapult 372 | - ce_aaa_server 373 | - ce_aaa_server_host 374 | - ce_acl 375 | - ce_acl_advance 376 | - ce_acl_interface 377 | - ce_bfd_global 378 | - ce_bfd_session 379 | - ce_bfd_view 380 | - ce_bgp 381 | - ce_bgp_af 382 | - ce_bgp_neighbor 383 | - ce_bgp_neighbor_af 384 | - ce_command 385 | - ce_config 386 | - ce_dldp 387 | - ce_dldp_interface 388 | - ce_eth_trunk 389 | - ce_evpn_bd_vni 390 | - ce_evpn_bgp 391 | - ce_evpn_bgp_rr 392 | - ce_evpn_global 393 | - ce_facts 394 | - ce_file_copy 395 | - ce_info_center_debug 396 | - ce_info_center_global 397 | - ce_info_center_log 398 | - ce_info_center_trap 399 | - ce_interface 400 | - ce_interface_ospf 401 | - ce_ip_interface 402 | - ce_link_status 403 | - ce_mlag_config 404 | - ce_mlag_interface 405 | - ce_mtu 406 | - ce_netconf 407 | - ce_netstream_aging 408 | - ce_netstream_export 409 | - ce_netstream_global 410 | - ce_netstream_template 411 | - ce_ntp 412 | - ce_ntp_auth 413 | - ce_ospf 414 | - ce_ospf_vrf 415 | - ce_reboot 416 | - ce_rollback 417 | - ce_sflow 418 | - ce_snmp_community 419 | - ce_snmp_contact 420 | - ce_snmp_location 421 | - ce_snmp_target_host 422 | - ce_snmp_traps 423 | - ce_snmp_user 424 | - ce_startup 425 | - ce_static_route 426 | - ce_stp 427 | - ce_switchport 428 | - ce_vlan 429 | - ce_vrf 430 | - ce_vrf_af 431 | - ce_vrf_interface 432 | - ce_vrrp 433 | - ce_vxlan_arp 434 | - ce_vxlan_gateway 435 | - ce_vxlan_global 436 | - ce_vxlan_tunnel 437 | - ce_vxlan_vap 438 | - circonus_annotation 439 | - cisco_spark 440 | - cl_bond 441 | - cl_bridge 442 | - cl_img_install 443 | - cl_interface 444 | - cl_interface_policy 445 | - cl_license 446 | - cl_ports 447 | - clc_aa_policy 448 | - clc_alert_policy 449 | - clc_blueprint_package 450 | - clc_firewall_policy 451 | - clc_group 452 | - clc_loadbalancer 453 | - clc_modify_server 454 | - clc_publicip 455 | - clc_server 456 | - clc_server_snapshot 457 | - cloud_init_data_facts 458 | - cloudflare_dns 459 | - cloudformation 460 | - cloudformation_facts 461 | - cloudfront_distribution 462 | - cloudfront_facts 463 | - cloudfront_invalidation 464 | - cloudfront_origin_access_identity 465 | - cloudscale_floating_ip 466 | - cloudscale_server 467 | - cloudtrail 468 | - cloudwatchevent_rule 469 | - cloudwatchlogs_log_group 470 | - cloudwatchlogs_log_group_facts 471 | - cnos_backup 472 | - cnos_bgp 473 | - cnos_command 474 | - cnos_conditional_command 475 | - cnos_conditional_template 476 | - cnos_config 477 | - cnos_factory 478 | - cnos_facts 479 | - cnos_image 480 | - cnos_interface 481 | - cnos_portchannel 482 | - cnos_reload 483 | - cnos_rollback 484 | - cnos_save 485 | - cnos_showrun 486 | - cnos_template 487 | - cnos_vlag 488 | - cnos_vlan 489 | - command 490 | - composer 491 | - consul 492 | - consul_acl 493 | - consul_kv 494 | - consul_session 495 | - copy 496 | - cpanm 497 | - cron 498 | - cronvar 499 | - crypttab 500 | - cs_account 501 | - cs_affinitygroup 502 | - cs_cluster 503 | - cs_configuration 504 | - cs_domain 505 | - cs_facts 506 | - cs_firewall 507 | - cs_host 508 | - cs_instance 509 | - cs_instance_facts 510 | - cs_instance_nic 511 | - cs_instance_nic_secondaryip 512 | - cs_instancegroup 513 | - cs_ip_address 514 | - cs_iso 515 | - cs_loadbalancer_rule 516 | - cs_loadbalancer_rule_member 517 | - cs_network 518 | - cs_network_acl 519 | - cs_network_acl_rule 520 | - cs_network_offering 521 | - cs_nic 522 | - cs_pod 523 | - cs_portforward 524 | - cs_project 525 | - cs_region 526 | - cs_resourcelimit 527 | - cs_role 528 | - cs_role_permission 529 | - cs_router 530 | - cs_securitygroup 531 | - cs_securitygroup_rule 532 | - cs_service_offering 533 | - cs_snapshot_policy 534 | - cs_sshkeypair 535 | - cs_staticnat 536 | - cs_storage_pool 537 | - cs_template 538 | - cs_user 539 | - cs_vmsnapshot 540 | - cs_volume 541 | - cs_vpc 542 | - cs_vpc_offering 543 | - cs_vpn_connection 544 | - cs_vpn_customer_gateway 545 | - cs_vpn_gateway 546 | - cs_zone 547 | - cs_zone_facts 548 | - cv_server_provision 549 | - cyberark_authentication 550 | - cyberark_user 551 | - data_pipeline 552 | - datadog_event 553 | - datadog_monitor 554 | - dconf 555 | - debconf 556 | - debug 557 | - dellos10_command 558 | - dellos10_config 559 | - dellos10_facts 560 | - dellos6_command 561 | - dellos6_config 562 | - dellos6_facts 563 | - dellos9_command 564 | - dellos9_config 565 | - dellos9_facts 566 | - deploy_helper 567 | - digital_ocean 568 | - digital_ocean_account_facts 569 | - digital_ocean_block_storage 570 | - digital_ocean_certificate 571 | - digital_ocean_certificate_facts 572 | - digital_ocean_domain 573 | - digital_ocean_domain_facts 574 | - digital_ocean_floating_ip 575 | - digital_ocean_floating_ip_facts 576 | - digital_ocean_image_facts 577 | - digital_ocean_load_balancer_facts 578 | - digital_ocean_region_facts 579 | - digital_ocean_size_facts 580 | - digital_ocean_snapshot_facts 581 | - digital_ocean_sshkey 582 | - digital_ocean_sshkey_facts 583 | - digital_ocean_tag 584 | - digital_ocean_tag_facts 585 | - digital_ocean_volume_facts 586 | - dimensiondata_network 587 | - dimensiondata_vlan 588 | - django_manage 589 | - dladm_etherstub 590 | - dladm_iptun 591 | - dladm_linkprop 592 | - dladm_vlan 593 | - dladm_vnic 594 | - dnf 595 | - dnsimple 596 | - dnsmadeeasy 597 | - docker 598 | - docker_container 599 | - docker_image 600 | - docker_image_facts 601 | - docker_login 602 | - docker_network 603 | - docker_secret 604 | - docker_service 605 | - docker_volume 606 | - dpkg_selections 607 | - dynamodb_table 608 | - dynamodb_ttl 609 | - easy_install 610 | - ec2 611 | - ec2_ami 612 | - ec2_ami_copy 613 | - ec2_ami_facts 614 | - ec2_ami_find 615 | - ec2_ami_search 616 | - ec2_asg 617 | - ec2_asg_facts 618 | - ec2_asg_lifecycle_hook 619 | - ec2_customer_gateway 620 | - ec2_customer_gateway_facts 621 | - ec2_eip 622 | - ec2_eip_facts 623 | - ec2_elb 624 | - ec2_elb_facts 625 | - ec2_elb_lb 626 | - ec2_eni 627 | - ec2_eni_facts 628 | - ec2_facts 629 | - ec2_group 630 | - ec2_group_facts 631 | - ec2_instance 632 | - ec2_instance_facts 633 | - ec2_key 634 | - ec2_lc 635 | - ec2_lc_facts 636 | - ec2_lc_find 637 | - ec2_metadata_facts 638 | - ec2_metric_alarm 639 | - ec2_placement_group 640 | - ec2_placement_group_facts 641 | - ec2_remote_facts 642 | - ec2_scaling_policy 643 | - ec2_snapshot 644 | - ec2_snapshot_copy 645 | - ec2_snapshot_facts 646 | - ec2_tag 647 | - ec2_vol 648 | - ec2_vol_facts 649 | - ec2_vpc 650 | - ec2_vpc_dhcp_option 651 | - ec2_vpc_dhcp_option_facts 652 | - ec2_vpc_dhcp_options 653 | - ec2_vpc_dhcp_options_facts 654 | - ec2_vpc_egress_igw 655 | - ec2_vpc_endpoint 656 | - ec2_vpc_endpoint_facts 657 | - ec2_vpc_igw 658 | - ec2_vpc_igw_facts 659 | - ec2_vpc_nacl 660 | - ec2_vpc_nacl_facts 661 | - ec2_vpc_nat_gateway 662 | - ec2_vpc_nat_gateway_facts 663 | - ec2_vpc_net 664 | - ec2_vpc_net_facts 665 | - ec2_vpc_peer 666 | - ec2_vpc_peering_facts 667 | - ec2_vpc_route_table 668 | - ec2_vpc_route_table_facts 669 | - ec2_vpc_subnet 670 | - ec2_vpc_subnet_facts 671 | - ec2_vpc_vgw 672 | - ec2_vpc_vgw_facts 673 | - ec2_vpc_vpn 674 | - ec2_vpc_vpn_facts 675 | - ec2_win_password 676 | - ecs_attribute 677 | - ecs_cluster 678 | - ecs_ecr 679 | - ecs_service 680 | - ecs_service_facts 681 | - ecs_task 682 | - ecs_taskdefinition 683 | - ecs_taskdefinition_facts 684 | - edgeos_command 685 | - edgeos_config 686 | - edgeos_facts 687 | - efs 688 | - efs_facts 689 | - ejabberd_user 690 | - elasticache 691 | - elasticache_facts 692 | - elasticache_parameter_group 693 | - elasticache_snapshot 694 | - elasticache_subnet_group 695 | - elasticsearch_plugin 696 | - elb_application_lb 697 | - elb_application_lb_facts 698 | - elb_classic_lb 699 | - elb_classic_lb_facts 700 | - elb_instance 701 | - elb_network_lb 702 | - elb_target 703 | - elb_target_group 704 | - elb_target_group_facts 705 | - enos_command 706 | - enos_config 707 | - enos_facts 708 | - eos_banner 709 | - eos_command 710 | - eos_config 711 | - eos_eapi 712 | - eos_facts 713 | - eos_interface 714 | - eos_l2_interface 715 | - eos_l3_interface 716 | - eos_linkagg 717 | - eos_lldp 718 | - eos_logging 719 | - eos_static_route 720 | - eos_system 721 | - eos_user 722 | - eos_vlan 723 | - eos_vrf 724 | - etcd3 725 | - execute_lambda 726 | - exo_dns_domain 727 | - exo_dns_record 728 | - exos_command 729 | - expect 730 | - facter 731 | - fail 732 | - fetch 733 | - file 734 | - filesystem 735 | - find 736 | - firewalld 737 | - flatpak 738 | - flatpak_remote 739 | - flowadm 740 | - flowdock 741 | - fmgr_script 742 | - foreman 743 | - fortios_address 744 | - fortios_config 745 | - fortios_ipv4_policy 746 | - fortios_webfilter 747 | - gc_storage 748 | - gcdns_record 749 | - gcdns_zone 750 | - gce 751 | - gce_eip 752 | - gce_img 753 | - gce_instance_template 754 | - gce_labels 755 | - gce_lb 756 | - gce_mig 757 | - gce_net 758 | - gce_pd 759 | - gce_snapshot 760 | - gce_tag 761 | - gconftool2 762 | - gcp_backend_service 763 | - gcp_compute_address 764 | - gcp_compute_backend_bucket 765 | - gcp_compute_backend_service 766 | - gcp_compute_disk 767 | - gcp_compute_firewall 768 | - gcp_compute_forwarding_rule 769 | - gcp_compute_global_address 770 | - gcp_compute_global_forwarding_rule 771 | - gcp_compute_health_check 772 | - gcp_compute_http_health_check 773 | - gcp_compute_https_health_check 774 | - gcp_compute_image 775 | - gcp_compute_instance 776 | - gcp_compute_instance_group 777 | - gcp_compute_instance_group_manager 778 | - gcp_compute_instance_template 779 | - gcp_compute_network 780 | - gcp_compute_route 781 | - gcp_compute_ssl_certificate 782 | - gcp_compute_subnetwork 783 | - gcp_compute_target_http_proxy 784 | - gcp_compute_target_https_proxy 785 | - gcp_compute_target_pool 786 | - gcp_compute_target_ssl_proxy 787 | - gcp_compute_target_tcp_proxy 788 | - gcp_compute_url_map 789 | - gcp_container_cluster 790 | - gcp_container_node_pool 791 | - gcp_dns_managed_zone 792 | - gcp_dns_resource_record_set 793 | - gcp_forwarding_rule 794 | - gcp_healthcheck 795 | - gcp_pubsub_subscription 796 | - gcp_pubsub_topic 797 | - gcp_storage_bucket 798 | - gcp_storage_bucket_access_control 799 | - gcp_target_proxy 800 | - gcp_url_map 801 | - gcpubsub 802 | - gcpubsub_facts 803 | - gcspanner 804 | - gem 805 | - get_url 806 | - getent 807 | - git 808 | - git_config 809 | - github_deploy_key 810 | - github_hooks 811 | - github_issue 812 | - github_key 813 | - github_release 814 | - gitlab_deploy_key 815 | - gitlab_group 816 | - gitlab_hooks 817 | - gitlab_project 818 | - gitlab_user 819 | - gluster_peer 820 | - gluster_volume 821 | - grafana_dashboard 822 | - grafana_datasource 823 | - grafana_plugin 824 | - group 825 | - group_by 826 | - grove 827 | - gunicorn 828 | - hall 829 | - haproxy 830 | - helm 831 | - heroku_collaborator 832 | - hg 833 | - hipchat 834 | - homebrew 835 | - homebrew_cask 836 | - homebrew_tap 837 | - honeybadger_deployment 838 | - hostname 839 | - hpilo_boot 840 | - hpilo_facts 841 | - hponcfg 842 | - htpasswd 843 | - iam 844 | - iam_cert 845 | - iam_cert_facts 846 | - iam_group 847 | - iam_managed_policy 848 | - iam_mfa_device_facts 849 | - iam_policy 850 | - iam_role 851 | - iam_role_facts 852 | - iam_server_certificate_facts 853 | - iam_user 854 | - icinga2_feature 855 | - icinga2_host 856 | - imc_rest 857 | - imgadm 858 | - import_playbook 859 | - import_role 860 | - import_tasks 861 | - include 862 | - include_role 863 | - include_tasks 864 | - include_vars 865 | - infini_export 866 | - infini_export_client 867 | - infini_fs 868 | - infini_host 869 | - infini_pool 870 | - infini_vol 871 | - infinity 872 | - influxdb_database 873 | - influxdb_query 874 | - influxdb_retention_policy 875 | - influxdb_user 876 | - influxdb_write 877 | - ini_file 878 | - interfaces_file 879 | - ios_banner 880 | - ios_command 881 | - ios_config 882 | - ios_facts 883 | - ios_interface 884 | - ios_l2_interface 885 | - ios_l3_interface 886 | - ios_linkagg 887 | - ios_lldp 888 | - ios_logging 889 | - ios_ping 890 | - ios_static_route 891 | - ios_system 892 | - ios_user 893 | - ios_vlan 894 | - ios_vrf 895 | - iosxr_banner 896 | - iosxr_command 897 | - iosxr_config 898 | - iosxr_facts 899 | - iosxr_interface 900 | - iosxr_logging 901 | - iosxr_netconf 902 | - iosxr_system 903 | - iosxr_user 904 | - ip_netns 905 | - ipa_dnsrecord 906 | - ipa_dnszone 907 | - ipa_group 908 | - ipa_hbacrule 909 | - ipa_host 910 | - ipa_hostgroup 911 | - ipa_role 912 | - ipa_service 913 | - ipa_subca 914 | - ipa_sudocmd 915 | - ipa_sudocmdgroup 916 | - ipa_sudorule 917 | - ipa_user 918 | - ipadm_addr 919 | - ipadm_addrprop 920 | - ipadm_if 921 | - ipadm_ifprop 922 | - ipadm_prop 923 | - ipify_facts 924 | - ipinfoio_facts 925 | - ipmi_boot 926 | - ipmi_power 927 | - iptables 928 | - irc 929 | - ironware_command 930 | - ironware_config 931 | - ironware_facts 932 | - iso_extract 933 | - jabber 934 | - java_cert 935 | - jboss 936 | - jenkins_job 937 | - jenkins_job_facts 938 | - jenkins_plugin 939 | - jenkins_script 940 | - jira 941 | - junos_banner 942 | - junos_command 943 | - junos_config 944 | - junos_facts 945 | - junos_interface 946 | - junos_l2_interface 947 | - junos_l3_interface 948 | - junos_linkagg 949 | - junos_lldp 950 | - junos_lldp_interface 951 | - junos_logging 952 | - junos_netconf 953 | - junos_package 954 | - junos_rpc 955 | - junos_scp 956 | - junos_static_route 957 | - junos_system 958 | - junos_user 959 | - junos_vlan 960 | - junos_vrf 961 | - k8s 962 | - k8s_raw 963 | - k8s_scale 964 | - katello 965 | - kernel_blacklist 966 | - keycloak_client 967 | - keycloak_clienttemplate 968 | - kibana_plugin 969 | - kinesis_stream 970 | - known_hosts 971 | - kubernetes 972 | - lambda 973 | - lambda_alias 974 | - lambda_event 975 | - lambda_facts 976 | - lambda_policy 977 | - layman 978 | - ldap_attr 979 | - ldap_entry 980 | - ldap_passwd 981 | - letsencrypt 982 | - librato_annotation 983 | - lightsail 984 | - lineinfile 985 | - linode 986 | - lldp 987 | - locale_gen 988 | - logentries 989 | - logentries_msg 990 | - logicmonitor 991 | - logicmonitor_facts 992 | - logstash_plugin 993 | - lvg 994 | - lvol 995 | - lxc_container 996 | - lxd_container 997 | - lxd_profile 998 | - macports 999 | - mail 1000 | - make 1001 | - manageiq_alert_profiles 1002 | - manageiq_alerts 1003 | - manageiq_policies 1004 | - manageiq_provider 1005 | - manageiq_tags 1006 | - manageiq_user 1007 | - mattermost 1008 | - maven_artifact 1009 | - memset_dns_reload 1010 | - memset_zone 1011 | - memset_zone_domain 1012 | - memset_zone_record 1013 | - meraki_admin 1014 | - meraki_network 1015 | - meraki_organization 1016 | - meraki_snmp 1017 | - meta 1018 | - mksysb 1019 | - modprobe 1020 | - mongodb_parameter 1021 | - mongodb_user 1022 | - monit 1023 | - mount 1024 | - mqtt 1025 | - mssql_db 1026 | - mysql_db 1027 | - mysql_replication 1028 | - mysql_user 1029 | - mysql_variables 1030 | - na_cdot_aggregate 1031 | - na_cdot_license 1032 | - na_cdot_lun 1033 | - na_cdot_qtree 1034 | - na_cdot_svm 1035 | - na_cdot_user 1036 | - na_cdot_user_role 1037 | - na_cdot_volume 1038 | - na_ontap_aggregate 1039 | - na_ontap_broadcast_domain 1040 | - na_ontap_broadcast_domain_ports 1041 | - na_ontap_cifs 1042 | - na_ontap_cifs_acl 1043 | - na_ontap_cifs_server 1044 | - na_ontap_cluster 1045 | - na_ontap_cluster_ha 1046 | - na_ontap_export_policy 1047 | - na_ontap_export_policy_rule 1048 | - na_ontap_igroup 1049 | - na_ontap_interface 1050 | - na_ontap_iscsi 1051 | - na_ontap_job_schedule 1052 | - na_ontap_license 1053 | - na_ontap_lun 1054 | - na_ontap_lun_map 1055 | - na_ontap_net_ifgrp 1056 | - na_ontap_net_port 1057 | - na_ontap_net_routes 1058 | - na_ontap_net_vlan 1059 | - na_ontap_nfs 1060 | - na_ontap_ntp 1061 | - na_ontap_qtree 1062 | - na_ontap_service_processor_network 1063 | - na_ontap_snapshot 1064 | - na_ontap_snmp 1065 | - na_ontap_svm 1066 | - na_ontap_ucadapter 1067 | - na_ontap_user 1068 | - na_ontap_user_role 1069 | - na_ontap_volume 1070 | - na_ontap_volume_clone 1071 | - nagios 1072 | - nclu 1073 | - net_banner 1074 | - net_get 1075 | - net_interface 1076 | - net_l2_interface 1077 | - net_l3_interface 1078 | - net_linkagg 1079 | - net_lldp 1080 | - net_lldp_interface 1081 | - net_logging 1082 | - net_ping 1083 | - net_put 1084 | - net_static_route 1085 | - net_system 1086 | - net_user 1087 | - net_vlan 1088 | - net_vrf 1089 | - netact_cm_command 1090 | - netapp_e_amg 1091 | - netapp_e_amg_role 1092 | - netapp_e_amg_sync 1093 | - netapp_e_auth 1094 | - netapp_e_facts 1095 | - netapp_e_flashcache 1096 | - netapp_e_host 1097 | - netapp_e_hostgroup 1098 | - netapp_e_lun_mapping 1099 | - netapp_e_snapshot_group 1100 | - netapp_e_snapshot_images 1101 | - netapp_e_snapshot_volume 1102 | - netapp_e_storage_system 1103 | - netapp_e_storagepool 1104 | - netapp_e_volume 1105 | - netapp_e_volume_copy 1106 | - netconf_config 1107 | - netconf_get 1108 | - netconf_rpc 1109 | - netscaler 1110 | - netscaler_cs_action 1111 | - netscaler_cs_policy 1112 | - netscaler_cs_vserver 1113 | - netscaler_gslb_service 1114 | - netscaler_gslb_site 1115 | - netscaler_gslb_vserver 1116 | - netscaler_lb_monitor 1117 | - netscaler_lb_vserver 1118 | - netscaler_nitro_request 1119 | - netscaler_save_config 1120 | - netscaler_server 1121 | - netscaler_service 1122 | - netscaler_servicegroup 1123 | - netscaler_ssl_certkey 1124 | - newrelic_deployment 1125 | - nexmo 1126 | - nginx_status_facts 1127 | - nios_dns_view 1128 | - nios_host_record 1129 | - nios_network 1130 | - nios_network_view 1131 | - nios_zone 1132 | - nmcli 1133 | - nosh 1134 | - npm 1135 | - nso_action 1136 | - nso_config 1137 | - nso_query 1138 | - nso_show 1139 | - nso_verify 1140 | - nsupdate 1141 | - nuage_vspk 1142 | - nxos_aaa_server 1143 | - nxos_aaa_server_host 1144 | - nxos_acl 1145 | - nxos_acl_interface 1146 | - nxos_banner 1147 | - nxos_bgp 1148 | - nxos_bgp_af 1149 | - nxos_bgp_neighbor 1150 | - nxos_bgp_neighbor_af 1151 | - nxos_command 1152 | - nxos_config 1153 | - nxos_evpn_global 1154 | - nxos_evpn_vni 1155 | - nxos_facts 1156 | - nxos_feature 1157 | - nxos_file_copy 1158 | - nxos_gir 1159 | - nxos_gir_profile_management 1160 | - nxos_hsrp 1161 | - nxos_igmp 1162 | - nxos_igmp_interface 1163 | - nxos_igmp_snooping 1164 | - nxos_install_os 1165 | - nxos_interface 1166 | - nxos_interface_ospf 1167 | - nxos_ip_interface 1168 | - nxos_l2_interface 1169 | - nxos_l3_interface 1170 | - nxos_linkagg 1171 | - nxos_lldp 1172 | - nxos_logging 1173 | - nxos_mtu 1174 | - nxos_ntp 1175 | - nxos_ntp_auth 1176 | - nxos_ntp_options 1177 | - nxos_nxapi 1178 | - nxos_ospf 1179 | - nxos_ospf_vrf 1180 | - nxos_overlay_global 1181 | - nxos_pim 1182 | - nxos_pim_interface 1183 | - nxos_pim_rp_address 1184 | - nxos_ping 1185 | - nxos_portchannel 1186 | - nxos_reboot 1187 | - nxos_rollback 1188 | - nxos_smu 1189 | - nxos_snapshot 1190 | - nxos_snmp_community 1191 | - nxos_snmp_contact 1192 | - nxos_snmp_host 1193 | - nxos_snmp_location 1194 | - nxos_snmp_traps 1195 | - nxos_snmp_user 1196 | - nxos_static_route 1197 | - nxos_switchport 1198 | - nxos_system 1199 | - nxos_udld 1200 | - nxos_udld_interface 1201 | - nxos_user 1202 | - nxos_vlan 1203 | - nxos_vpc 1204 | - nxos_vpc_interface 1205 | - nxos_vrf 1206 | - nxos_vrf_af 1207 | - nxos_vrf_interface 1208 | - nxos_vrrp 1209 | - nxos_vtp_domain 1210 | - nxos_vtp_password 1211 | - nxos_vtp_version 1212 | - nxos_vxlan_vtep 1213 | - nxos_vxlan_vtep_vni 1214 | - oc 1215 | - office_365_connector_card 1216 | - ohai 1217 | - omapi_host 1218 | - one_host 1219 | - one_image 1220 | - one_image_facts 1221 | - one_service 1222 | - one_vm 1223 | - oneandone_firewall_policy 1224 | - oneandone_load_balancer 1225 | - oneandone_monitoring_policy 1226 | - oneandone_private_network 1227 | - oneandone_public_ip 1228 | - oneandone_server 1229 | - oneview_datacenter_facts 1230 | - oneview_enclosure_facts 1231 | - oneview_ethernet_network 1232 | - oneview_ethernet_network_facts 1233 | - oneview_fc_network 1234 | - oneview_fc_network_facts 1235 | - oneview_fcoe_network 1236 | - oneview_fcoe_network_facts 1237 | - oneview_logical_interconnect_group 1238 | - oneview_logical_interconnect_group_facts 1239 | - oneview_network_set 1240 | - oneview_network_set_facts 1241 | - oneview_san_manager 1242 | - oneview_san_manager_facts 1243 | - onyx_bgp 1244 | - onyx_command 1245 | - onyx_config 1246 | - onyx_facts 1247 | - onyx_interface 1248 | - onyx_l2_interface 1249 | - onyx_l3_interface 1250 | - onyx_linkagg 1251 | - onyx_lldp 1252 | - onyx_lldp_interface 1253 | - onyx_magp 1254 | - onyx_mlag_ipl 1255 | - onyx_mlag_vip 1256 | - onyx_ospf 1257 | - onyx_pfc_interface 1258 | - onyx_protocol 1259 | - onyx_vlan 1260 | - open_iscsi 1261 | - openbsd_pkg 1262 | - opendj_backendprop 1263 | - openshift_raw 1264 | - openshift_scale 1265 | - openssl_certificate 1266 | - openssl_csr 1267 | - openssl_dhparam 1268 | - openssl_privatekey 1269 | - openssl_publickey 1270 | - openvswitch_bridge 1271 | - openvswitch_db 1272 | - openvswitch_port 1273 | - openwrt_init 1274 | - opkg 1275 | - ordnance_config 1276 | - ordnance_facts 1277 | - os_auth 1278 | - os_client_config 1279 | - os_flavor_facts 1280 | - os_floating_ip 1281 | - os_group 1282 | - os_image 1283 | - os_image_facts 1284 | - os_ironic 1285 | - os_ironic_inspect 1286 | - os_ironic_node 1287 | - os_keypair 1288 | - os_keystone_domain 1289 | - os_keystone_domain_facts 1290 | - os_keystone_endpoint 1291 | - os_keystone_role 1292 | - os_keystone_service 1293 | - os_network 1294 | - os_networks_facts 1295 | - os_nova_flavor 1296 | - os_nova_host_aggregate 1297 | - os_object 1298 | - os_port 1299 | - os_port_facts 1300 | - os_project 1301 | - os_project_access 1302 | - os_project_facts 1303 | - os_quota 1304 | - os_recordset 1305 | - os_router 1306 | - os_security_group 1307 | - os_security_group_rule 1308 | - os_server 1309 | - os_server_action 1310 | - os_server_actions 1311 | - os_server_facts 1312 | - os_server_group 1313 | - os_server_metadata 1314 | - os_server_volume 1315 | - os_stack 1316 | - os_subnet 1317 | - os_subnets_facts 1318 | - os_user 1319 | - os_user_facts 1320 | - os_user_group 1321 | - os_user_role 1322 | - os_volume 1323 | - os_volume_snapshot 1324 | - os_zone 1325 | - osx_defaults 1326 | - osx_say 1327 | - ovh_ip_loadbalancing_backend 1328 | - ovirt 1329 | - ovirt_affinity_group 1330 | - ovirt_affinity_groups 1331 | - ovirt_affinity_label 1332 | - ovirt_affinity_label_facts 1333 | - ovirt_affinity_labels 1334 | - ovirt_affinity_labels_facts 1335 | - ovirt_api_facts 1336 | - ovirt_auth 1337 | - ovirt_cluster 1338 | - ovirt_cluster_facts 1339 | - ovirt_clusters 1340 | - ovirt_clusters_facts 1341 | - ovirt_datacenter 1342 | - ovirt_datacenter_facts 1343 | - ovirt_datacenters 1344 | - ovirt_datacenters_facts 1345 | - ovirt_disk 1346 | - ovirt_disk_facts 1347 | - ovirt_disks 1348 | - ovirt_external_provider 1349 | - ovirt_external_provider_facts 1350 | - ovirt_external_providers 1351 | - ovirt_external_providers_facts 1352 | - ovirt_group 1353 | - ovirt_group_facts 1354 | - ovirt_groups 1355 | - ovirt_groups_facts 1356 | - ovirt_host_networks 1357 | - ovirt_host_pm 1358 | - ovirt_host_storage_facts 1359 | - ovirt_hosts 1360 | - ovirt_hosts_facts 1361 | - ovirt_mac_pools 1362 | - ovirt_networks 1363 | - ovirt_networks_facts 1364 | - ovirt_nics 1365 | - ovirt_nics_facts 1366 | - ovirt_permissions 1367 | - ovirt_permissions_facts 1368 | - ovirt_quotas 1369 | - ovirt_quotas_facts 1370 | - ovirt_scheduling_policies_facts 1371 | - ovirt_snapshots 1372 | - ovirt_snapshots_facts 1373 | - ovirt_storage_connections 1374 | - ovirt_storage_domains 1375 | - ovirt_storage_domains_facts 1376 | - ovirt_storage_templates_facts 1377 | - ovirt_storage_vms_facts 1378 | - ovirt_tags 1379 | - ovirt_tags_facts 1380 | - ovirt_templates 1381 | - ovirt_templates_facts 1382 | - ovirt_users 1383 | - ovirt_users_facts 1384 | - ovirt_vmpools 1385 | - ovirt_vmpools_facts 1386 | - ovirt_vms 1387 | - ovirt_vms_facts 1388 | - pacemaker_cluster 1389 | - package 1390 | - package_facts 1391 | - packet_device 1392 | - packet_sshkey 1393 | - pacman 1394 | - pagerduty 1395 | - pagerduty_alert 1396 | - pam_limits 1397 | - pamd 1398 | - panos_admin 1399 | - panos_admpwd 1400 | - panos_cert_gen_ssh 1401 | - panos_check 1402 | - panos_commit 1403 | - panos_dag 1404 | - panos_dag_tags 1405 | - panos_import 1406 | - panos_interface 1407 | - panos_lic 1408 | - panos_loadcfg 1409 | - panos_match_rule 1410 | - panos_mgtconfig 1411 | - panos_nat_policy 1412 | - panos_nat_rule 1413 | - panos_object 1414 | - panos_op 1415 | - panos_pg 1416 | - panos_query_rules 1417 | - panos_restart 1418 | - panos_sag 1419 | - panos_security_policy 1420 | - panos_security_rule 1421 | - parted 1422 | - patch 1423 | - pause 1424 | - pear 1425 | - ping 1426 | - pingdom 1427 | - pip 1428 | - pkg5 1429 | - pkg5_publisher 1430 | - pkgin 1431 | - pkgng 1432 | - pkgutil 1433 | - pn_cluster 1434 | - pn_ospf 1435 | - pn_ospfarea 1436 | - pn_show 1437 | - pn_trunk 1438 | - pn_vlag 1439 | - pn_vlan 1440 | - pn_vrouter 1441 | - pn_vrouterbgp 1442 | - pn_vrouterif 1443 | - pn_vrouterlbif 1444 | - portage 1445 | - portinstall 1446 | - postgresql_db 1447 | - postgresql_ext 1448 | - postgresql_lang 1449 | - postgresql_privs 1450 | - postgresql_schema 1451 | - postgresql_user 1452 | - profitbricks 1453 | - profitbricks_datacenter 1454 | - profitbricks_nic 1455 | - profitbricks_volume 1456 | - profitbricks_volume_attachments 1457 | - proxmox 1458 | - proxmox_kvm 1459 | - proxmox_template 1460 | - proxysql_backend_servers 1461 | - proxysql_global_variables 1462 | - proxysql_manage_config 1463 | - proxysql_mysql_users 1464 | - proxysql_query_rules 1465 | - proxysql_replication_hostgroups 1466 | - proxysql_scheduler 1467 | - psexec 1468 | - pubnub_blocks 1469 | - pulp_repo 1470 | - puppet 1471 | - purefa_ds 1472 | - purefa_facts 1473 | - purefa_hg 1474 | - purefa_host 1475 | - purefa_pg 1476 | - purefa_pgsnap 1477 | - purefa_snap 1478 | - purefa_volume 1479 | - purefb_fs 1480 | - purefb_snap 1481 | - pushbullet 1482 | - pushover 1483 | - rabbitmq_binding 1484 | - rabbitmq_exchange 1485 | - rabbitmq_parameter 1486 | - rabbitmq_plugin 1487 | - rabbitmq_policy 1488 | - rabbitmq_queue 1489 | - rabbitmq_user 1490 | - rabbitmq_vhost 1491 | - raw 1492 | - rax 1493 | - rax_cbs 1494 | - rax_cbs_attachments 1495 | - rax_cdb 1496 | - rax_cdb_database 1497 | - rax_cdb_user 1498 | - rax_clb 1499 | - rax_clb_nodes 1500 | - rax_clb_ssl 1501 | - rax_dns 1502 | - rax_dns_record 1503 | - rax_facts 1504 | - rax_files 1505 | - rax_files_objects 1506 | - rax_identity 1507 | - rax_keypair 1508 | - rax_meta 1509 | - rax_mon_alarm 1510 | - rax_mon_check 1511 | - rax_mon_entity 1512 | - rax_mon_notification 1513 | - rax_mon_notification_plan 1514 | - rax_network 1515 | - rax_queue 1516 | - rax_scaling_group 1517 | - rax_scaling_policy 1518 | - rds 1519 | - rds_instance_facts 1520 | - rds_param_group 1521 | - rds_snapshot_facts 1522 | - rds_subnet_group 1523 | - redhat_subscription 1524 | - redis 1525 | - redshift 1526 | - redshift_facts 1527 | - redshift_subnet_group 1528 | - replace 1529 | - rhevm 1530 | - rhn_channel 1531 | - rhn_register 1532 | - rhsm_repository 1533 | - riak 1534 | - rocketchat 1535 | - rollbar_deployment 1536 | - route53 1537 | - route53_facts 1538 | - route53_health_check 1539 | - route53_zone 1540 | - rpm_key 1541 | - rundeck_acl_policy 1542 | - rundeck_project 1543 | - runit 1544 | - s3 1545 | - s3_bucket 1546 | - s3_lifecycle 1547 | - s3_logging 1548 | - s3_sync 1549 | - s3_website 1550 | - say 1551 | - scaleway_compute 1552 | - scaleway_sshkey 1553 | - script 1554 | - seboolean 1555 | - sefcontext 1556 | - selinux 1557 | - selinux_permissive 1558 | - sendgrid 1559 | - sensu_check 1560 | - sensu_client 1561 | - sensu_handler 1562 | - sensu_silence 1563 | - sensu_subscription 1564 | - seport 1565 | - serverless 1566 | - service 1567 | - service_facts 1568 | - set_fact 1569 | - set_stats 1570 | - setup 1571 | - sf_account_manager 1572 | - sf_check_connections 1573 | - sf_snapshot_schedule_manager 1574 | - sf_volume_access_group_manager 1575 | - sf_volume_manager 1576 | - shell 1577 | - sl_vm 1578 | - slack 1579 | - slackpkg 1580 | - slurp 1581 | - slxos_command 1582 | - slxos_config 1583 | - slxos_facts 1584 | - slxos_interface 1585 | - slxos_l2_interface 1586 | - slxos_l3_interface 1587 | - slxos_linkagg 1588 | - slxos_vlan 1589 | - smartos_image_facts 1590 | - snmp_facts 1591 | - snow_record 1592 | - sns 1593 | - sns_topic 1594 | - solaris_zone 1595 | - sorcery 1596 | - spectrum_device 1597 | - spotinst_aws_elastigroup 1598 | - sqs_queue 1599 | - sros_command 1600 | - sros_config 1601 | - sros_rollback 1602 | - stackdriver 1603 | - stacki_host 1604 | - stat 1605 | - statusio_maintenance 1606 | - sts_assume_role 1607 | - sts_session_token 1608 | - subversion 1609 | - supervisorctl 1610 | - svc 1611 | - svr4pkg 1612 | - swdepot 1613 | - swupd 1614 | - synchronize 1615 | - sysctl 1616 | - syslogger 1617 | - systemd 1618 | - sysvinit 1619 | - taiga_issue 1620 | - telegram 1621 | - telnet 1622 | - tempfile 1623 | - template 1624 | - terraform 1625 | - timezone 1626 | - tower_credential 1627 | - tower_group 1628 | - tower_host 1629 | - tower_inventory 1630 | - tower_job_cancel 1631 | - tower_job_launch 1632 | - tower_job_list 1633 | - tower_job_template 1634 | - tower_job_wait 1635 | - tower_label 1636 | - tower_organization 1637 | - tower_project 1638 | - tower_role 1639 | - tower_team 1640 | - tower_user 1641 | - twilio 1642 | - typetalk 1643 | - ucs_ip_pool 1644 | - ucs_lan_connectivity 1645 | - ucs_mac_pool 1646 | - ucs_san_connectivity 1647 | - ucs_vhba_template 1648 | - ucs_vlans 1649 | - ucs_vnic_template 1650 | - ucs_vsans 1651 | - ucs_wwn_pool 1652 | - udm_dns_record 1653 | - udm_dns_zone 1654 | - udm_group 1655 | - udm_share 1656 | - udm_user 1657 | - ufw 1658 | - unarchive 1659 | - uptimerobot 1660 | - uri 1661 | - urpmi 1662 | - user 1663 | - vca_fw 1664 | - vca_nat 1665 | - vca_vapp 1666 | - vcenter_folder 1667 | - vcenter_license 1668 | - vdirect_commit 1669 | - vdirect_file 1670 | - vdirect_runnable 1671 | - vdo 1672 | - vertica_configuration 1673 | - vertica_facts 1674 | - vertica_role 1675 | - vertica_schema 1676 | - vertica_user 1677 | - virt 1678 | - virt_net 1679 | - virt_pool 1680 | - vmadm 1681 | - vmware_cfg_backup 1682 | - vmware_cluster 1683 | - vmware_cluster_facts 1684 | - vmware_datacenter 1685 | - vmware_datastore_cluster 1686 | - vmware_datastore_facts 1687 | - vmware_datastore_maintenancemode 1688 | - vmware_dns_config 1689 | - vmware_drs_rule_facts 1690 | - vmware_dvs_host 1691 | - vmware_dvs_portgroup 1692 | - vmware_dvswitch 1693 | - vmware_guest 1694 | - vmware_guest_disk_facts 1695 | - vmware_guest_facts 1696 | - vmware_guest_file_operation 1697 | - vmware_guest_find 1698 | - vmware_guest_powerstate 1699 | - vmware_guest_snapshot 1700 | - vmware_guest_snapshot_facts 1701 | - vmware_guest_tools_wait 1702 | - vmware_host 1703 | - vmware_host_acceptance 1704 | - vmware_host_capability_facts 1705 | - vmware_host_config_facts 1706 | - vmware_host_config_manager 1707 | - vmware_host_datastore 1708 | - vmware_host_dns_facts 1709 | - vmware_host_facts 1710 | - vmware_host_firewall_facts 1711 | - vmware_host_firewall_manager 1712 | - vmware_host_lockdown 1713 | - vmware_host_ntp 1714 | - vmware_host_package_facts 1715 | - vmware_host_powerstate 1716 | - vmware_host_service_facts 1717 | - vmware_host_service_manager 1718 | - vmware_host_vmnic_facts 1719 | - vmware_local_role_manager 1720 | - vmware_local_user_facts 1721 | - vmware_local_user_manager 1722 | - vmware_maintenancemode 1723 | - vmware_migrate_vmk 1724 | - vmware_portgroup 1725 | - vmware_portgroup_facts 1726 | - vmware_resource_pool 1727 | - vmware_resource_pool_facts 1728 | - vmware_tag 1729 | - vmware_tag_facts 1730 | - vmware_target_canonical_facts 1731 | - vmware_vm_facts 1732 | - vmware_vm_shell 1733 | - vmware_vm_vm_drs_rule 1734 | - vmware_vm_vss_dvs_migrate 1735 | - vmware_vmkernel 1736 | - vmware_vmkernel_facts 1737 | - vmware_vmkernel_ip_config 1738 | - vmware_vmotion 1739 | - vmware_vsan_cluster 1740 | - vmware_vswitch 1741 | - vmware_vswitch_facts 1742 | - vr_account_facts 1743 | - vr_dns_domain 1744 | - vr_dns_record 1745 | - vr_firewall_group 1746 | - vr_firewall_rule 1747 | - vr_server 1748 | - vr_ssh_key 1749 | - vr_startup_script 1750 | - vr_user 1751 | - vsphere_copy 1752 | - vsphere_guest 1753 | - vyos_banner 1754 | - vyos_command 1755 | - vyos_config 1756 | - vyos_facts 1757 | - vyos_interface 1758 | - vyos_l3_interface 1759 | - vyos_linkagg 1760 | - vyos_lldp 1761 | - vyos_lldp_interface 1762 | - vyos_logging 1763 | - vyos_static_route 1764 | - vyos_system 1765 | - vyos_user 1766 | - vyos_vlan 1767 | - wait_for 1768 | - wait_for_connection 1769 | - wakeonlan 1770 | - webfaction_app 1771 | - webfaction_db 1772 | - webfaction_domain 1773 | - webfaction_mailbox 1774 | - webfaction_site 1775 | - win_acl 1776 | - win_acl_inheritance 1777 | - win_audit_policy_system 1778 | - win_audit_rule 1779 | - win_certificate_store 1780 | - win_chocolatey 1781 | - win_command 1782 | - win_copy 1783 | - win_defrag 1784 | - win_disk_facts 1785 | - win_disk_image 1786 | - win_dns_client 1787 | - win_domain 1788 | - win_domain_computer 1789 | - win_domain_controller 1790 | - win_domain_group 1791 | - win_domain_membership 1792 | - win_domain_user 1793 | - win_dotnet_ngen 1794 | - win_dsc 1795 | - win_environment 1796 | - win_eventlog 1797 | - win_eventlog_entry 1798 | - win_feature 1799 | - win_file 1800 | - win_file_version 1801 | - win_find 1802 | - win_firewall 1803 | - win_firewall_rule 1804 | - win_get_url 1805 | - win_group 1806 | - win_group_membership 1807 | - win_hostname 1808 | - win_hotfix 1809 | - win_iis_virtualdirectory 1810 | - win_iis_webapplication 1811 | - win_iis_webapppool 1812 | - win_iis_webbinding 1813 | - win_iis_website 1814 | - win_lineinfile 1815 | - win_mapped_drive 1816 | - win_msg 1817 | - win_msi 1818 | - win_nssm 1819 | - win_owner 1820 | - win_package 1821 | - win_pagefile 1822 | - win_path 1823 | - win_pester 1824 | - win_ping 1825 | - win_power_plan 1826 | - win_product_facts 1827 | - win_psexec 1828 | - win_psmodule 1829 | - win_rabbitmq_plugin 1830 | - win_reboot 1831 | - win_reg_stat 1832 | - win_regedit 1833 | - win_region 1834 | - win_regmerge 1835 | - win_robocopy 1836 | - win_route 1837 | - win_say 1838 | - win_scheduled_task 1839 | - win_scheduled_task_stat 1840 | - win_security_policy 1841 | - win_service 1842 | - win_share 1843 | - win_shell 1844 | - win_shortcut 1845 | - win_stat 1846 | - win_tempfile 1847 | - win_template 1848 | - win_timezone 1849 | - win_toast 1850 | - win_unzip 1851 | - win_updates 1852 | - win_uri 1853 | - win_user 1854 | - win_user_right 1855 | - win_wait_for 1856 | - win_wakeonlan 1857 | - win_webpicmd 1858 | - win_whoami 1859 | - xattr 1860 | - xbps 1861 | - xenserver_facts 1862 | - xml 1863 | - yarn 1864 | - yum 1865 | - yum_repository 1866 | - zabbix_group 1867 | - zabbix_group_facts 1868 | - zabbix_host 1869 | - zabbix_hostmacro 1870 | - zabbix_maintenance 1871 | - zabbix_proxy 1872 | - zabbix_screen 1873 | - zabbix_template 1874 | - zfs 1875 | - zfs_facts 1876 | - znode 1877 | - zpool_facts 1878 | - zypper 1879 | - zypper_repository 1880 | -------------------------------------------------------------------------------- /ansible_kernel/play_args.py: -------------------------------------------------------------------------------- 1 | play_args = [ 2 | 'name', 3 | 'hosts', 4 | 'become', 5 | 'become_method', 6 | 'gather_facts' 7 | ] 8 | -------------------------------------------------------------------------------- /ansible_kernel/plugins/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ansible/ansible-jupyter-kernel/09efa5d4073a72d1d56cce60574c743a1feb1954/ansible_kernel/plugins/__init__.py -------------------------------------------------------------------------------- /ansible_kernel/plugins/callback/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ansible/ansible-jupyter-kernel/09efa5d4073a72d1d56cce60574c743a1feb1954/ansible_kernel/plugins/callback/__init__.py -------------------------------------------------------------------------------- /ansible_kernel/plugins/callback/ansible_kernel_helper.py: -------------------------------------------------------------------------------- 1 | from __future__ import (absolute_import, division, print_function) 2 | __metaclass__ = type 3 | 4 | from ansible.plugins.callback import CallbackBase 5 | from ansible.playbook.task_include import TaskInclude 6 | import json 7 | import zmq 8 | import os 9 | 10 | 11 | from functools import wraps 12 | 13 | DEBUG = True 14 | 15 | 16 | def debug(fn): 17 | if DEBUG: 18 | @wraps(fn) 19 | def wrapper(*args, **kwargs): 20 | print('Calling', fn) 21 | ret_value = fn(*args, **kwargs) 22 | return ret_value 23 | return wrapper 24 | else: 25 | return fn 26 | 27 | 28 | class CallbackModule(CallbackBase): 29 | ''' 30 | This callback sends task results to ansible kernel and waits for the next task before proceeding. 31 | ''' 32 | 33 | CALLBACK_VERSION = 2.0 34 | CALLBACK_TYPE = 'aggregate' 35 | CALLBACK_NAME = 'ansible_kernel_helper' 36 | CALLBACK_NEEDS_WHITELIST = True 37 | 38 | def __init__(self): 39 | super(CallbackModule, self).__init__() 40 | self.zmq_context = zmq.Context() 41 | self.socket = self.zmq_context.socket(zmq.PUSH) 42 | self.status_port = os.getenv('ANSIBLE_KERNEL_STATUS_PORT') 43 | if self.status_port: 44 | self.socket.connect("tcp://127.0.0.1:{0}".format(self.status_port)) 45 | else: 46 | self.socket = None 47 | self.task = None 48 | self.play = None 49 | self.hosts = [] 50 | 51 | def _format_output(self, result): 52 | if 'stdout_lines' in result: 53 | return '\n'.join(result['stdout_lines']) 54 | return "" 55 | 56 | def _format_error(self, result): 57 | if 'stderr_lines' in result: 58 | return '\n'.join(result['stderr_lines']) 59 | return "" 60 | 61 | def _dump_results(self, result): 62 | 63 | r = result.copy() 64 | if 'invocation' in r: 65 | del r['invocation'] 66 | if 'stdout' in r: 67 | if r['stdout']: 68 | r['stdout'] = '[see below]' 69 | if 'stdout_lines' in r: 70 | if r['stdout_lines']: 71 | r['stdout_lines'] = '[removed for clarity]' 72 | if 'stderr' in r: 73 | if r['stderr']: 74 | r['stderr'] = '[see below]' 75 | if 'stderr_lines' in r: 76 | if r['stderr_lines']: 77 | r['stderr_lines'] = '[removed for clarity]' 78 | if 'changed' in r: 79 | del r['changed'] 80 | if 'reason' in r: 81 | return r['reason'] 82 | return super(CallbackModule, self)._dump_results(r, indent=4, sort_keys=True) 83 | 84 | @debug 85 | def v2_playbook_on_setup(self): 86 | pass 87 | 88 | @debug 89 | def v2_playbook_on_handler_task_start(self, task): 90 | if self.socket is None: 91 | return 92 | args = '' 93 | if not task.no_log: 94 | args = u', '.join(u'%s=%s' % a for a in task.args.items()) 95 | args = u' %s' % args 96 | self.socket.send_string(json.dumps(['TaskStart', dict(task_name=task.get_name().strip(), 97 | task_arg=args, 98 | task_id=str(task._uuid))])) 99 | 100 | @debug 101 | def v2_runner_on_ok(self, result): 102 | if self.socket is None: 103 | return 104 | if isinstance(result._task, TaskInclude): 105 | return 106 | delegated_vars = result._result.get('_ansible_delegated_vars', {}) 107 | self._clean_results(result._result, result._task.action) 108 | self.socket.send_string(json.dumps(['TaskStatus', dict(task_name=self.task.get_name().strip(), 109 | device_name=result._host.get_name(), 110 | delegated_host_name=str(delegated_vars.get('ansible_host', '')), 111 | changed=result._result.get('changed', False), 112 | failed=False, 113 | unreachable=False, 114 | skipped=False, 115 | results=self._dump_results(result._result), 116 | output=self._format_output(result._result), 117 | error=self._format_error(result._result), 118 | task_id=str(result._task._uuid))])) 119 | 120 | @debug 121 | def v2_runner_on_failed(self, result, ignore_errors=False): 122 | if self.socket is None: 123 | return 124 | delegated_vars = result._result.get('_ansible_delegated_vars', {}) 125 | self._clean_results(result._result, result._task.action) 126 | self.socket.send_string(json.dumps(['TaskStatus', dict(task_name=self.task.get_name().strip(), 127 | device_name=result._host.get_name(), 128 | changed=False, 129 | failed=True, 130 | unreachable=False, 131 | skipped=False, 132 | delegated_host_name=str(delegated_vars.get('ansible_host', '')), 133 | results=self._dump_results(result._result), 134 | output=self._format_output(result._result), 135 | error=self._format_error(result._result), 136 | task_id=str(result._task._uuid))])) 137 | 138 | @debug 139 | def runner_on_unreachable(self, host, result, ignore_errors=False): 140 | if self.socket is None: 141 | return 142 | self.socket.send_string(json.dumps(['TaskStatus', dict(task_name=self.task.get_name().strip(), 143 | device_name=host, 144 | changed=False, 145 | failed=False, 146 | unreachable=True, 147 | skipped=False, 148 | task_id=str(self.task._uuid))])) 149 | 150 | @debug 151 | def v2_runner_item_on_skipped(self, result, ignore_errors=False): 152 | if self.socket is None: 153 | return 154 | self.socket.send_string(json.dumps(['TaskStatus', dict(task_name=self.task.get_name().strip(), 155 | changed=False, 156 | failed=False, 157 | unreachable=False, 158 | skipped=True, 159 | task_id=str(result._task._uuid))])) 160 | 161 | @debug 162 | def DISABLED_v2_on_any(self, *args, **kwargs): 163 | if self.socket is None: 164 | return 165 | self._display.display("--- play: {} task: {} ---".format(getattr(self.play, 'name', None), self.task)) 166 | 167 | self._display.display(" --- ARGS ") 168 | for i, a in enumerate(args): 169 | self._display.display(' %s: %s' % (i, a)) 170 | 171 | self._display.display(" --- KWARGS ") 172 | for k in kwargs: 173 | self._display.display(' %s: %s' % (k, kwargs[k])) 174 | 175 | @debug 176 | def v2_playbook_on_play_start(self, play): 177 | if self.socket is None: 178 | return 179 | self.play = play 180 | self.hosts = play.get_variable_manager()._inventory.get_hosts() 181 | 182 | for host in self.hosts: 183 | self.socket.send_string(json.dumps(['DeviceStatus', dict(name=host.get_name())])) 184 | 185 | @debug 186 | def v2_playbook_on_task_start(self, task, is_conditional): 187 | if self.socket is None: 188 | return 189 | self.task = task 190 | args = '' 191 | if not task.no_log: 192 | args = u', '.join(u'%s=%s' % a for a in task.args.items()) 193 | args = u' %s' % args 194 | self.socket.send_string(json.dumps(['TaskStart', dict(task_name=task.get_name().strip(), 195 | task_arg=args, 196 | task_id=str(task._uuid))])) 197 | 198 | @debug 199 | def v2_playbook_on_stats(self, stats): 200 | if self.socket is None: 201 | return 202 | for host in self.hosts: 203 | s = stats.summarize(host.get_name()) 204 | status = "pass" 205 | status = "fail" if s['failures'] > 0 else status 206 | status = "fail" if s['unreachable'] > 0 else status 207 | self.socket.send_string(json.dumps(['DeviceStatus', dict(name=host.get_name())])) 208 | self.socket.send_string(json.dumps(['PlaybookEnded', dict()])) 209 | 210 | @debug 211 | def v2_playbook_on_no_hosts_remaining(self): 212 | if self.socket is None: 213 | return 214 | -------------------------------------------------------------------------------- /ansible_kernel/roles/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ansible/ansible-jupyter-kernel/09efa5d4073a72d1d56cce60574c743a1feb1954/ansible_kernel/roles/__init__.py -------------------------------------------------------------------------------- /ansible_kernel/roles/ansible_kernel_helpers/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ansible/ansible-jupyter-kernel/09efa5d4073a72d1d56cce60574c743a1feb1954/ansible_kernel/roles/ansible_kernel_helpers/__init__.py -------------------------------------------------------------------------------- /ansible_kernel/roles/ansible_kernel_helpers/action_plugins/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ansible/ansible-jupyter-kernel/09efa5d4073a72d1d56cce60574c743a1feb1954/ansible_kernel/roles/ansible_kernel_helpers/action_plugins/__init__.py -------------------------------------------------------------------------------- /ansible_kernel/roles/ansible_kernel_helpers/action_plugins/pause_for_kernel.py: -------------------------------------------------------------------------------- 1 | from ansible.plugins.action import ActionBase 2 | 3 | import zmq 4 | 5 | 6 | class ActionModule(ActionBase): 7 | 8 | BYPASS_HOST_LOOP = True 9 | 10 | def run(self, tmp=None, task_vars=None): 11 | # print ('pause_for_kernel') 12 | if task_vars is None: 13 | task_vars = dict() 14 | host = self._task.args.get('host', None) 15 | port = self._task.args.get('port', None) 16 | task_num = self._task.args.get('task_num', None) 17 | # print (task_num) 18 | result = super(ActionModule, self).run(tmp, task_vars) 19 | 20 | context = zmq.Context() 21 | socket = context.socket(zmq.REQ) 22 | socket.setsockopt(zmq.LINGER, 0) 23 | # print ('connecting...') 24 | socket.connect("tcp://{0}:{1}".format(host, port)) 25 | # print ('connected') 26 | # print ('sending...') 27 | socket.send_string("{0}".format(task_num)) 28 | # print ('sent') 29 | # print ('waiting...') 30 | socket.recv() 31 | # print ('received') 32 | # print ('closing...') 33 | socket.close() 34 | # print ('closed') 35 | return result 36 | -------------------------------------------------------------------------------- /ansible_kernel/roles/ansible_kernel_helpers/library/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ansible/ansible-jupyter-kernel/09efa5d4073a72d1d56cce60574c743a1feb1954/ansible_kernel/roles/ansible_kernel_helpers/library/__init__.py -------------------------------------------------------------------------------- /ansible_kernel/roles/ansible_kernel_helpers/library/pause_for_kernel.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ansible/ansible-jupyter-kernel/09efa5d4073a72d1d56cce60574c743a1feb1954/ansible_kernel/roles/ansible_kernel_helpers/library/pause_for_kernel.py -------------------------------------------------------------------------------- /ansible_kernel/task_args.py: -------------------------------------------------------------------------------- 1 | 2 | task_args = [ 3 | 'name', 4 | 'when', 5 | 'with_items', 6 | 'register' 7 | ] 8 | -------------------------------------------------------------------------------- /ansible_kernel/templates/ansible_playbook.tpl: -------------------------------------------------------------------------------- 1 | {%- extends 'null.tpl' -%} 2 | 3 | {%- block header -%} 4 | --- 5 | {% endblock header %} 6 | 7 | {% block input -%} 8 | {% if cell.source.strip().startswith("#inventory")-%} 9 | {% elif cell.source.strip().startswith("#ansible.cfg")-%} 10 | {% elif cell.source.strip().startswith("#template")-%} 11 | {% elif cell.source.strip().startswith("#vars")-%} 12 | {% elif cell.source.strip().startswith("#host_vars")-%} 13 | {% elif cell.source.strip().startswith("#group_vars")-%} 14 | {% elif cell.source.strip().startswith("#play") %} 15 | {% if cell.source.strip()[5:].strip() %}- {%endif%}{{cell.source.strip()[5:].strip() | indent(2) | trim}} 16 | tasks: 17 | {% elif cell.source.strip().startswith("#task") %} 18 | {% if cell.source.strip()[5:].strip() %} - {%endif%}{{cell.source.strip()[5:].strip() | indent(4) | trim}} 19 | {%else%} 20 | {% if cell.source.strip() %} - {%endif%}{{cell.source.strip() | indent(4) | trim}} 21 | {%endif%} 22 | {% endblock input %} 23 | 24 | {% block markdowncell scoped %} 25 | {{ cell.source | comment_lines }} 26 | {% endblock markdowncell %} 27 | 28 | {%- block footer -%} 29 | ... 30 | {% endblock footer %} 31 | -------------------------------------------------------------------------------- /ansible_kernel/templates/ansible_tasks.tpl: -------------------------------------------------------------------------------- 1 | {%- extends 'null.tpl' -%} 2 | 3 | {%- block header -%} 4 | --- 5 | {% endblock header %} 6 | 7 | {% block input -%} 8 | {% if cell.source.strip().startswith("#inventory")%} 9 | {% elif cell.source.strip().startswith("#host_vars")%} 10 | {% elif cell.source.strip().startswith("#group_vars")%} 11 | {% elif cell.source.strip().startswith("#play") %} 12 | {% elif cell.source.strip().startswith("#task") %} 13 | {% if cell.source.strip()[5:].strip() %}- {%endif%}{{cell.source.strip()[5:].strip() | indent(2) | trim}} 14 | {%else%} 15 | {% if cell.source.strip() %}- {%endif%}{{cell.source.strip() | indent(2) | trim}} 16 | {%endif%} 17 | {% endblock input %} 18 | 19 | 20 | {% block markdowncell scoped %} 21 | {{ cell.source | comment_lines }} 22 | {% endblock markdowncell %} 23 | 24 | {%- block footer -%} 25 | ... 26 | {% endblock footer %} 27 | -------------------------------------------------------------------------------- /ansible_kernel/update_module_cache.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | 5 | """ 6 | Usage: 7 | update_module_cache [options] 8 | 9 | Options: 10 | -h, --help Show this page 11 | --debug Show debug logging 12 | --verbose Show verbose logging 13 | """ 14 | from __future__ import print_function 15 | from docopt import docopt 16 | import logging 17 | import sys 18 | import yaml 19 | from tqdm import tqdm 20 | from subprocess import Popen, STDOUT, PIPE 21 | import pkg_resources 22 | 23 | logger = logging.getLogger('update_module_cache') 24 | 25 | 26 | def parse_ansible_doc(output): 27 | lines = output.splitlines() 28 | lines.reverse() 29 | 30 | args = [] 31 | 32 | state = 'start' 33 | 34 | while lines: 35 | 36 | line = lines.pop() 37 | 38 | # start 39 | if state == 'start' and line.startswith("OPTIONS"): 40 | state = 'options' 41 | elif state == 'start': 42 | continue 43 | elif state == 'options' and line.startswith("AUTHOR"): 44 | break 45 | elif state == 'options' and line.startswith("EXAMPLES"): 46 | break 47 | elif state == 'options' and line.startswith("NOTES"): 48 | break 49 | elif state == 'options' and line.startswith("REQUIREMENTS"): 50 | break 51 | elif state == 'options' and line.startswith("- "): 52 | args.append(line[2:]) 53 | elif state == 'options' and line.startswith("= "): 54 | args.append(line[2:]) 55 | 56 | return args 57 | 58 | 59 | def main(args=None): 60 | if args is None: 61 | args = sys.argv[1:] 62 | parsed_args = docopt(__doc__, args) 63 | if parsed_args['--debug']: 64 | logging.basicConfig(level=logging.DEBUG) 65 | elif parsed_args['--verbose']: 66 | logging.basicConfig(level=logging.INFO) 67 | else: 68 | logging.basicConfig(level=logging.WARNING) 69 | print("Updating module cache") 70 | p = Popen(['ansible-doc', '-t', 'module', '-l'], 71 | stdout=PIPE, stderr=STDOUT) 72 | output = p.communicate()[0] 73 | 74 | modules = [] 75 | module_args = {} 76 | for line in output.splitlines(): 77 | module_name = (line.split(' ')[0]) 78 | modules.append(module_name) 79 | 80 | with open(pkg_resources.resource_filename('ansible_kernel', 'modules.yml'), 'w') as f: 81 | f.write(yaml.safe_dump(modules, default_flow_style=False)) 82 | 83 | for module_name in tqdm(modules): 84 | p = Popen(['ansible-doc', '-t', 'module', module_name], 85 | stdout=PIPE, stderr=STDOUT) 86 | output = p.communicate()[0] 87 | args = parse_ansible_doc(output) 88 | module_args[module_name] = args 89 | 90 | with open(pkg_resources.resource_filename('ansible_kernel', 'module_args.yml'), 'w') as f: 91 | f.write(yaml.safe_dump(module_args, default_flow_style=False)) 92 | 93 | return 0 94 | 95 | 96 | if __name__ == '__main__': 97 | sys.exit(main(sys.argv[1:])) 98 | -------------------------------------------------------------------------------- /ansible_kernel/widgets.py: -------------------------------------------------------------------------------- 1 | import ipywidgets as widgets 2 | from traitlets import Unicode 3 | 4 | 5 | class VaultPassword(widgets.Password): 6 | ansible_kernel_property = Unicode('vault_password').tag(sync=True) 7 | 8 | 9 | class SSHPassword(widgets.Password): 10 | ansible_kernel_property = Unicode('ssh_password').tag(sync=True) 11 | 12 | 13 | class SSHPrivateKey(widgets.Password): 14 | ansible_kernel_property = Unicode('ssh_private_key').tag(sync=True) 15 | -------------------------------------------------------------------------------- /docs/ansible_jupyter_kernel_vimeo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ansible/ansible-jupyter-kernel/09efa5d4073a72d1d56cce60574c743a1feb1954/docs/ansible_jupyter_kernel_vimeo.png -------------------------------------------------------------------------------- /docs/example_session.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ansible/ansible-jupyter-kernel/09efa5d4073a72d1d56cce60574c743a1feb1954/docs/example_session.png -------------------------------------------------------------------------------- /notebooks/HelloWorld.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Hello World for Ansible Jupyter Kernel\n", 8 | "\n", 9 | "Runs a task using Ansible.\n", 10 | "\n", 11 | "Press shift-enter to run the task.\n", 12 | "\n", 13 | "Press shift-tab to get task docs. Press the ^ icon to expand the docs." 14 | ] 15 | }, 16 | { 17 | "cell_type": "code", 18 | "execution_count": 5, 19 | "metadata": {}, 20 | "outputs": [ 21 | { 22 | "name": "stdout", 23 | "output_type": "stream", 24 | "text": [ 25 | "TASK [debug] *******************************************************************\n", 26 | "ok: [localhost] => {\n", 27 | " \"msg\": \"Hello world!\"\n", 28 | "}\n" 29 | ] 30 | } 31 | ], 32 | "source": [ 33 | "debug:" 34 | ] 35 | }, 36 | { 37 | "cell_type": "code", 38 | "execution_count": 1, 39 | "metadata": {}, 40 | "outputs": [ 41 | { 42 | "name": "stdout", 43 | "output_type": "stream", 44 | "text": [ 45 | "TASK [ping] ********************************************************************\n", 46 | "ok: [localhost] => {\"ping\": \"pong\"}\n" 47 | ] 48 | } 49 | ], 50 | "source": [ 51 | "ping:" 52 | ] 53 | }, 54 | { 55 | "cell_type": "code", 56 | "execution_count": null, 57 | "metadata": {}, 58 | "outputs": [], 59 | "source": [] 60 | } 61 | ], 62 | "metadata": { 63 | "kernelspec": { 64 | "display_name": "Ansible", 65 | "language": "ansible", 66 | "name": "ansible" 67 | }, 68 | "language_info": { 69 | "codemirror_mode": "yaml", 70 | "file_extension": ".yml", 71 | "mimetype": "text/yaml", 72 | "name": "ansible" 73 | } 74 | }, 75 | "nbformat": 4, 76 | "nbformat_minor": 2 77 | } 78 | -------------------------------------------------------------------------------- /notebooks/HelloWorldAnsibleJupyterWigets.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Uses widgets as input to tasks" 8 | ] 9 | }, 10 | { 11 | "cell_type": "code", 12 | "execution_count": 1, 13 | "metadata": {}, 14 | "outputs": [], 15 | "source": [ 16 | "#ansible.cfg\n", 17 | "[defaults]\n", 18 | "roles_path=roles" 19 | ] 20 | }, 21 | { 22 | "cell_type": "code", 23 | "execution_count": 2, 24 | "metadata": {}, 25 | "outputs": [ 26 | { 27 | "name": "stdout", 28 | "output_type": "stream", 29 | "text": [ 30 | "- downloading role 'ansible_jupyter_widgets', owned by benthomasson\n", 31 | "- downloading role from https://github.com/benthomasson/ansible-jupyter-widgets/archive/master.tar.gz\n", 32 | "- extracting benthomasson.ansible_jupyter_widgets to /private/var/folders/p8/mttm7w913kq_v0wyfl9khlpc0000gn/T/ansible_kernel_playbook2QAHbc/project/roles/benthomasson.ansible_jupyter_widgets\n", 33 | "- benthomasson.ansible_jupyter_widgets (master) was installed successfully\n", 34 | "- downloading role 'jupyter_tools', owned by benthomasson\n", 35 | "- downloading role from https://github.com/benthomasson/jupyter-tools/archive/master.tar.gz\n", 36 | "- extracting benthomasson.jupyter_tools to /private/var/folders/p8/mttm7w913kq_v0wyfl9khlpc0000gn/T/ansible_kernel_playbook2QAHbc/project/roles/benthomasson.jupyter_tools\n", 37 | "- benthomasson.jupyter_tools (master) was installed successfully\n", 38 | "\n" 39 | ] 40 | } 41 | ], 42 | "source": [ 43 | "#play\n", 44 | "hosts: localhost\n", 45 | "gather_facts: false\n", 46 | "roles:\n", 47 | " - benthomasson.ansible_jupyter_widgets\n", 48 | " - benthomasson.jupyter_tools" 49 | ] 50 | }, 51 | { 52 | "cell_type": "code", 53 | "execution_count": 3, 54 | "metadata": {}, 55 | "outputs": [ 56 | { 57 | "name": "stdout", 58 | "output_type": "stream", 59 | "text": [ 60 | "TASK [int_slider] **************************************************************\n" 61 | ] 62 | }, 63 | { 64 | "data": { 65 | "application/vnd.jupyter.widget-view+json": { 66 | "model_id": "6c95cc3e832c4344908a2fe138139ddc", 67 | "version_major": 2, 68 | "version_minor": 0 69 | }, 70 | "text/plain": [ 71 | "IntSlider(value=0, description=u'y', var_name=u'y')" 72 | ] 73 | }, 74 | "metadata": {}, 75 | "output_type": "display_data" 76 | }, 77 | { 78 | "name": "stdout", 79 | "output_type": "stream", 80 | "text": [ 81 | "ok: [localhost] => {}\n" 82 | ] 83 | } 84 | ], 85 | "source": [ 86 | "int_slider:\n", 87 | " var_name: y" 88 | ] 89 | }, 90 | { 91 | "cell_type": "code", 92 | "execution_count": 4, 93 | "metadata": {}, 94 | "outputs": [ 95 | { 96 | "name": "stdout", 97 | "output_type": "stream", 98 | "text": [ 99 | "TASK [debug] *******************************************************************\n", 100 | "ok: [localhost] => {\n", 101 | " \"y\": 45\n", 102 | "}\n" 103 | ] 104 | } 105 | ], 106 | "source": [ 107 | "debug:\n", 108 | " var: y" 109 | ] 110 | }, 111 | { 112 | "cell_type": "code", 113 | "execution_count": 5, 114 | "metadata": {}, 115 | "outputs": [ 116 | { 117 | "name": "stdout", 118 | "output_type": "stream", 119 | "text": [ 120 | "TASK [text] ********************************************************************\n" 121 | ] 122 | }, 123 | { 124 | "data": { 125 | "application/vnd.jupyter.widget-view+json": { 126 | "model_id": "fdc70137e2d14fb69863f397e6c9f7d4", 127 | "version_major": 2, 128 | "version_minor": 0 129 | }, 130 | "text/plain": [ 131 | "Text(value=u'', description=u'target', var_name=u'target')" 132 | ] 133 | }, 134 | "metadata": {}, 135 | "output_type": "display_data" 136 | }, 137 | { 138 | "name": "stdout", 139 | "output_type": "stream", 140 | "text": [ 141 | "ok: [localhost] => {}\n" 142 | ] 143 | } 144 | ], 145 | "source": [ 146 | "text:\n", 147 | " var_name: target" 148 | ] 149 | }, 150 | { 151 | "cell_type": "code", 152 | "execution_count": 9, 153 | "metadata": {}, 154 | "outputs": [ 155 | { 156 | "name": "stdout", 157 | "output_type": "stream", 158 | "text": [ 159 | "TASK [html_template] ***********************************************************\n" 160 | ] 161 | }, 162 | { 163 | "data": { 164 | "text/html": [ 165 | "

Hello Ansible

\n" 166 | ] 167 | }, 168 | "metadata": {}, 169 | "output_type": "display_data" 170 | }, 171 | { 172 | "name": "stdout", 173 | "output_type": "stream", 174 | "text": [ 175 | "ok: [localhost] => {}\n" 176 | ] 177 | } 178 | ], 179 | "source": [ 180 | "html_template:\n", 181 | " src: templates/hello.j2" 182 | ] 183 | }, 184 | { 185 | "cell_type": "code", 186 | "execution_count": null, 187 | "metadata": {}, 188 | "outputs": [], 189 | "source": [] 190 | } 191 | ], 192 | "metadata": { 193 | "kernelspec": { 194 | "display_name": "Ansible", 195 | "language": "ansible", 196 | "name": "ansible" 197 | }, 198 | "language_info": { 199 | "codemirror_mode": "yaml", 200 | "file_extension": ".yml", 201 | "mimetype": "text/yaml", 202 | "name": "ansible" 203 | } 204 | }, 205 | "nbformat": 4, 206 | "nbformat_minor": 2 207 | } 208 | -------------------------------------------------------------------------------- /notebooks/HelloWorldDocumentation.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Hello World for Ansible Jupyter Kernel\n", 8 | "\n", 9 | "Runs a task using Ansible.\n", 10 | "\n", 11 | "Press shift-enter to run the task.\n", 12 | "\n", 13 | "Add a `?` and press shift-enter after a module name to bring up the ansible-doc in the pager." 14 | ] 15 | }, 16 | { 17 | "cell_type": "code", 18 | "execution_count": 18, 19 | "metadata": {}, 20 | "outputs": [ 21 | { 22 | "name": "stdout", 23 | "output_type": "stream", 24 | "text": [ 25 | "TASK [debug] *******************************************************************\n", 26 | "ok: [localhost] => {\n", 27 | " \"msg\": \"Hello world!\"\n", 28 | "}\n" 29 | ] 30 | } 31 | ], 32 | "source": [ 33 | "debug:" 34 | ] 35 | }, 36 | { 37 | "cell_type": "code", 38 | "execution_count": 19, 39 | "metadata": {}, 40 | "outputs": [], 41 | "source": [ 42 | "ping?" 43 | ] 44 | }, 45 | { 46 | "cell_type": "code", 47 | "execution_count": null, 48 | "metadata": {}, 49 | "outputs": [], 50 | "source": [] 51 | } 52 | ], 53 | "metadata": { 54 | "kernelspec": { 55 | "display_name": "Ansible", 56 | "language": "ansible", 57 | "name": "ansible" 58 | }, 59 | "language_info": { 60 | "codemirror_mode": "yaml", 61 | "file_extension": ".yml", 62 | "mimetype": "text/yaml", 63 | "name": "ansible" 64 | } 65 | }, 66 | "nbformat": 4, 67 | "nbformat_minor": 2 68 | } 69 | -------------------------------------------------------------------------------- /notebooks/HelloWorldGalaxyRole.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Installs a galaxy role and includes the role using the include_role module\n", 8 | "\n", 9 | "* This example includes the hello role in the playbook using include_role" 10 | ] 11 | }, 12 | { 13 | "cell_type": "code", 14 | "execution_count": 1, 15 | "metadata": {}, 16 | "outputs": [ 17 | { 18 | "name": "stdout", 19 | "output_type": "stream", 20 | "text": [ 21 | "\n" 22 | ] 23 | } 24 | ], 25 | "source": [ 26 | "#play\n", 27 | "hosts: localhost\n", 28 | "gather_facts: false" 29 | ] 30 | }, 31 | { 32 | "cell_type": "code", 33 | "execution_count": 2, 34 | "metadata": {}, 35 | "outputs": [ 36 | { 37 | "name": "stdout", 38 | "output_type": "stream", 39 | "text": [ 40 | "- downloading role 'hello_role', owned by benthomasson\n", 41 | "- downloading role from https://github.com/benthomasson/hello-role/archive/master.tar.gz\n", 42 | "- extracting benthomasson.hello_role to /private/var/folders/p8/mttm7w913kq_v0wyfl9khlpc0000gn/T/ansible_kernel_playbookkZaE51/roles/benthomasson.hello_role\n", 43 | "- benthomasson.hello_role (master) was installed successfully\n", 44 | "TASK [include_role : benthomasson.hello_role] **********************************\n", 45 | "TASK [benthomasson.hello_role : debug] *****************************************\n", 46 | "ok: [localhost] => {\n", 47 | " \"msg\": \"Hello world!\"\n", 48 | "}\n" 49 | ] 50 | } 51 | ], 52 | "source": [ 53 | "include_role:\n", 54 | " name: benthomasson.hello_role\n" 55 | ] 56 | }, 57 | { 58 | "cell_type": "code", 59 | "execution_count": null, 60 | "metadata": {}, 61 | "outputs": [], 62 | "source": [] 63 | }, 64 | { 65 | "cell_type": "code", 66 | "execution_count": null, 67 | "metadata": {}, 68 | "outputs": [], 69 | "source": [] 70 | } 71 | ], 72 | "metadata": { 73 | "kernelspec": { 74 | "display_name": "Ansible", 75 | "language": "ansible", 76 | "name": "ansible" 77 | }, 78 | "language_info": { 79 | "codemirror_mode": "yaml", 80 | "file_extension": ".yml", 81 | "mimetype": "text/yaml", 82 | "name": "ansible" 83 | } 84 | }, 85 | "nbformat": 4, 86 | "nbformat_minor": 2 87 | } 88 | -------------------------------------------------------------------------------- /notebooks/HelloWorldGalaxyRole2.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Installs a role from galaxy and includes the role in the roles list\n" 8 | ] 9 | }, 10 | { 11 | "cell_type": "code", 12 | "execution_count": 1, 13 | "metadata": {}, 14 | "outputs": [ 15 | { 16 | "name": "stdout", 17 | "output_type": "stream", 18 | "text": [ 19 | "- downloading role 'hello_role', owned by benthomasson\n", 20 | "- downloading role from https://github.com/benthomasson/hello-role/archive/master.tar.gz\n", 21 | "- extracting benthomasson.hello_role to /private/var/folders/p8/mttm7w913kq_v0wyfl9khlpc0000gn/T/ansible_kernel_playbookYibe_N/roles/benthomasson.hello_role\n", 22 | "- benthomasson.hello_role (master) was installed successfully\n", 23 | "\n", 24 | "TASK [benthomasson.hello_role : debug] *****************************************\n", 25 | "ok: [localhost] => {\n", 26 | " \"msg\": \"Hello world!\"\n", 27 | "}\n" 28 | ] 29 | } 30 | ], 31 | "source": [ 32 | "#play\n", 33 | "hosts: localhost\n", 34 | "gather_facts: false\n", 35 | "roles:\n", 36 | " - benthomasson.hello_role" 37 | ] 38 | }, 39 | { 40 | "cell_type": "code", 41 | "execution_count": null, 42 | "metadata": {}, 43 | "outputs": [], 44 | "source": [] 45 | }, 46 | { 47 | "cell_type": "code", 48 | "execution_count": null, 49 | "metadata": {}, 50 | "outputs": [], 51 | "source": [] 52 | } 53 | ], 54 | "metadata": { 55 | "kernelspec": { 56 | "display_name": "Ansible", 57 | "language": "ansible", 58 | "name": "ansible" 59 | }, 60 | "language_info": { 61 | "codemirror_mode": "yaml", 62 | "file_extension": ".yml", 63 | "mimetype": "text/yaml", 64 | "name": "ansible" 65 | } 66 | }, 67 | "nbformat": 4, 68 | "nbformat_minor": 2 69 | } 70 | -------------------------------------------------------------------------------- /notebooks/HelloWorldIncludeRole.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Includes a role using the include_role module\n", 8 | "\n", 9 | "* This example includes the hello role in the playbook using include_role\n", 10 | "* The 'hello' role is defined in the roles/hello directory\n", 11 | "* Make sure to run jupyter notebook from the notebooks directory for the roles_path to be set correctly" 12 | ] 13 | }, 14 | { 15 | "cell_type": "code", 16 | "execution_count": 4, 17 | "metadata": {}, 18 | "outputs": [], 19 | "source": [ 20 | "#ansible.cfg\n", 21 | "[defaults]\n", 22 | "roles_path=roles" 23 | ] 24 | }, 25 | { 26 | "cell_type": "code", 27 | "execution_count": 5, 28 | "metadata": {}, 29 | "outputs": [ 30 | { 31 | "name": "stdout", 32 | "output_type": "stream", 33 | "text": [ 34 | "\n" 35 | ] 36 | } 37 | ], 38 | "source": [ 39 | "#play\n", 40 | "hosts: localhost\n", 41 | "gather_facts: false" 42 | ] 43 | }, 44 | { 45 | "cell_type": "code", 46 | "execution_count": 6, 47 | "metadata": {}, 48 | "outputs": [ 49 | { 50 | "name": "stdout", 51 | "output_type": "stream", 52 | "text": [ 53 | "TASK [include_role : hello] ****************************************************\n", 54 | "TASK [hello : debug] ***********************************************************\n", 55 | "ok: [localhost] => {\n", 56 | " \"msg\": \"Hello world!\"\n", 57 | "}\n" 58 | ] 59 | } 60 | ], 61 | "source": [ 62 | "include_role:\n", 63 | " name: hello\n" 64 | ] 65 | }, 66 | { 67 | "cell_type": "code", 68 | "execution_count": null, 69 | "metadata": {}, 70 | "outputs": [], 71 | "source": [] 72 | }, 73 | { 74 | "cell_type": "code", 75 | "execution_count": null, 76 | "metadata": {}, 77 | "outputs": [], 78 | "source": [] 79 | } 80 | ], 81 | "metadata": { 82 | "kernelspec": { 83 | "display_name": "Ansible", 84 | "language": "ansible", 85 | "name": "ansible" 86 | }, 87 | "language_info": { 88 | "codemirror_mode": "yaml", 89 | "file_extension": ".yml", 90 | "mimetype": "text/yaml", 91 | "name": "ansible" 92 | } 93 | }, 94 | "nbformat": 4, 95 | "nbformat_minor": 2 96 | } 97 | -------------------------------------------------------------------------------- /notebooks/HelloWorldJupyterTools.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Installs the jupyter_tools role and uses html_template module\n" 8 | ] 9 | }, 10 | { 11 | "cell_type": "code", 12 | "execution_count": 1, 13 | "metadata": {}, 14 | "outputs": [ 15 | { 16 | "name": "stdout", 17 | "output_type": "stream", 18 | "text": [ 19 | "- downloading role 'jupyter_tools', owned by benthomasson\n", 20 | "- downloading role from https://github.com/benthomasson/jupyter-tools/archive/master.tar.gz\n", 21 | "- extracting benthomasson.jupyter_tools to /private/var/folders/p8/mttm7w913kq_v0wyfl9khlpc0000gn/T/ansible_kernel_playbookYyqqrl/project/roles/benthomasson.jupyter_tools\n", 22 | "- benthomasson.jupyter_tools (master) was installed successfully\n", 23 | "\n" 24 | ] 25 | } 26 | ], 27 | "source": [ 28 | "#play\n", 29 | "hosts: localhost\n", 30 | "gather_facts: false\n", 31 | "roles:\n", 32 | " - benthomasson.jupyter_tools\n", 33 | " " 34 | ] 35 | }, 36 | { 37 | "cell_type": "code", 38 | "execution_count": 2, 39 | "metadata": {}, 40 | "outputs": [ 41 | { 42 | "name": "stdout", 43 | "output_type": "stream", 44 | "text": [ 45 | "TASK [set_fact] ****************************************************************\n", 46 | "ok: [localhost] => {\n", 47 | " \"ansible_facts\": {\n", 48 | " \"target\": \"World\"\n", 49 | " }\n", 50 | "}\n" 51 | ] 52 | } 53 | ], 54 | "source": [ 55 | "set_fact:\n", 56 | " target: World" 57 | ] 58 | }, 59 | { 60 | "cell_type": "code", 61 | "execution_count": 3, 62 | "metadata": {}, 63 | "outputs": [ 64 | { 65 | "name": "stdout", 66 | "output_type": "stream", 67 | "text": [ 68 | "TASK [html_template] ***********************************************************\n" 69 | ] 70 | }, 71 | { 72 | "data": { 73 | "text/html": [ 74 | "

Hello World

\n" 75 | ] 76 | }, 77 | "metadata": {}, 78 | "output_type": "display_data" 79 | }, 80 | { 81 | "name": "stdout", 82 | "output_type": "stream", 83 | "text": [ 84 | "ok: [localhost] => {}\n" 85 | ] 86 | } 87 | ], 88 | "source": [ 89 | "html_template:\n", 90 | " src: templates/hello.j2" 91 | ] 92 | }, 93 | { 94 | "cell_type": "code", 95 | "execution_count": null, 96 | "metadata": {}, 97 | "outputs": [], 98 | "source": [] 99 | } 100 | ], 101 | "metadata": { 102 | "kernelspec": { 103 | "display_name": "Ansible", 104 | "language": "ansible", 105 | "name": "ansible" 106 | }, 107 | "language_info": { 108 | "codemirror_mode": "yaml", 109 | "file_extension": ".yml", 110 | "mimetype": "text/yaml", 111 | "name": "ansible" 112 | } 113 | }, 114 | "nbformat": 4, 115 | "nbformat_minor": 2 116 | } 117 | -------------------------------------------------------------------------------- /notebooks/HelloWorldPlaybook.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Hello World for Ansible Jupyter Notebook\n", 8 | "\n", 9 | "* Runs a playbook with a single task\n", 10 | "* Press shift-enter twice to run the play and the task" 11 | ] 12 | }, 13 | { 14 | "cell_type": "code", 15 | "execution_count": 1, 16 | "metadata": {}, 17 | "outputs": [ 18 | { 19 | "name": "stdout", 20 | "output_type": "stream", 21 | "text": [ 22 | "\n" 23 | ] 24 | } 25 | ], 26 | "source": [ 27 | "#play\n", 28 | "name: hello world\n", 29 | "hosts: localhost\n", 30 | "gather_facts: false" 31 | ] 32 | }, 33 | { 34 | "cell_type": "code", 35 | "execution_count": 2, 36 | "metadata": {}, 37 | "outputs": [ 38 | { 39 | "name": "stdout", 40 | "output_type": "stream", 41 | "text": [ 42 | "TASK [debug] *******************************************************************\n", 43 | "ok: [localhost] => {\n", 44 | " \"msg\": \"Hello world!\"\n", 45 | "}\n" 46 | ] 47 | } 48 | ], 49 | "source": [ 50 | "#task\n", 51 | "debug:" 52 | ] 53 | }, 54 | { 55 | "cell_type": "code", 56 | "execution_count": 1, 57 | "metadata": {}, 58 | "outputs": [ 59 | { 60 | "name": "stdout", 61 | "output_type": "stream", 62 | "text": [ 63 | "TASK [ping] ********************************************************************\n", 64 | "ok: [localhost] => {\"ping\": \"pong\"}\n" 65 | ] 66 | } 67 | ], 68 | "source": [ 69 | "#task\n", 70 | "ping:" 71 | ] 72 | }, 73 | { 74 | "cell_type": "code", 75 | "execution_count": null, 76 | "metadata": {}, 77 | "outputs": [], 78 | "source": [] 79 | } 80 | ], 81 | "metadata": { 82 | "kernelspec": { 83 | "display_name": "Ansible", 84 | "language": "ansible", 85 | "name": "ansible" 86 | }, 87 | "language_info": { 88 | "codemirror_mode": "yaml", 89 | "file_extension": ".yml", 90 | "mimetype": "text/yaml", 91 | "name": "ansible" 92 | } 93 | }, 94 | "nbformat": 4, 95 | "nbformat_minor": 2 96 | } 97 | -------------------------------------------------------------------------------- /notebooks/HelloWorldPlaybookWithInventory.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Hello World Playbook With Inventory for Ansible Jupyter Kernel\n", 8 | "\n", 9 | "* Defines an inventory\n", 10 | "* Defines a play\n", 11 | "* Defines a task\n", 12 | "\n", 13 | "* Press shift-enter three times to run the play and the task" 14 | ] 15 | }, 16 | { 17 | "cell_type": "code", 18 | "execution_count": 1, 19 | "metadata": {}, 20 | "outputs": [], 21 | "source": [ 22 | "#inventory\n", 23 | "[all]\n", 24 | "localhost" 25 | ] 26 | }, 27 | { 28 | "cell_type": "code", 29 | "execution_count": 2, 30 | "metadata": {}, 31 | "outputs": [ 32 | { 33 | "name": "stdout", 34 | "output_type": "stream", 35 | "text": [] 36 | } 37 | ], 38 | "source": [ 39 | "#play\n", 40 | "name: hello world\n", 41 | "hosts: localhost\n", 42 | "gather_facts: false" 43 | ] 44 | }, 45 | { 46 | "cell_type": "code", 47 | "execution_count": 4, 48 | "metadata": {}, 49 | "outputs": [ 50 | { 51 | "name": "stdout", 52 | "output_type": "stream", 53 | "text": [ 54 | "TASK [debug] *******************************************************************\n", 55 | "ok: [localhost] => {\n", 56 | " \"msg\": \"Hello world!\"\n", 57 | "}\n" 58 | ] 59 | } 60 | ], 61 | "source": [ 62 | "#task\n", 63 | "debug:" 64 | ] 65 | }, 66 | { 67 | "cell_type": "code", 68 | "execution_count": null, 69 | "metadata": {}, 70 | "outputs": [], 71 | "source": [] 72 | } 73 | ], 74 | "metadata": { 75 | "kernelspec": { 76 | "display_name": "Ansible", 77 | "language": "ansible", 78 | "name": "ansible" 79 | }, 80 | "language_info": { 81 | "codemirror_mode": "yaml", 82 | "file_extension": ".yml", 83 | "mimetype": "text/yaml", 84 | "name": "ansible" 85 | } 86 | }, 87 | "nbformat": 4, 88 | "nbformat_minor": 2 89 | } 90 | -------------------------------------------------------------------------------- /notebooks/HelloWorldPlaybookWithInventoryAndAnsibleCfg.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Hello World Playbook With Inventory and Ansible.cfg\n", 8 | "* Defines an ansible.cfg \n", 9 | "* Defines an inventory\n", 10 | "* Defines a play\n", 11 | "* Defines a task\n", 12 | "\n", 13 | "* Press shift-enter four times to run the play and task" 14 | ] 15 | }, 16 | { 17 | "cell_type": "code", 18 | "execution_count": 1, 19 | "metadata": {}, 20 | "outputs": [], 21 | "source": [ 22 | "#ansible.cfg\n", 23 | "[defaults]\n", 24 | "host_key_checking=False" 25 | ] 26 | }, 27 | { 28 | "cell_type": "code", 29 | "execution_count": 2, 30 | "metadata": {}, 31 | "outputs": [], 32 | "source": [ 33 | "#inventory\n", 34 | "[all]\n", 35 | "localhost ansible_connection=local" 36 | ] 37 | }, 38 | { 39 | "cell_type": "code", 40 | "execution_count": 3, 41 | "metadata": {}, 42 | "outputs": [ 43 | { 44 | "name": "stdout", 45 | "output_type": "stream", 46 | "text": [ 47 | "\n" 48 | ] 49 | } 50 | ], 51 | "source": [ 52 | "#play\n", 53 | "name: hello world\n", 54 | "hosts: localhost\n", 55 | "gather_facts: false" 56 | ] 57 | }, 58 | { 59 | "cell_type": "code", 60 | "execution_count": 4, 61 | "metadata": {}, 62 | "outputs": [ 63 | { 64 | "name": "stdout", 65 | "output_type": "stream", 66 | "text": [ 67 | "TASK [debug] *******************************************************************\n", 68 | "ok: [localhost] => {\n", 69 | " \"msg\": \"Hello World\"\n", 70 | "}\n" 71 | ] 72 | } 73 | ], 74 | "source": [ 75 | "#task\n", 76 | "debug:\n", 77 | " msg: Hello World" 78 | ] 79 | }, 80 | { 81 | "cell_type": "code", 82 | "execution_count": 5, 83 | "metadata": {}, 84 | "outputs": [ 85 | { 86 | "name": "stdout", 87 | "output_type": "stream", 88 | "text": [ 89 | "TASK [ping] ********************************************************************\n", 90 | "ok: [localhost] => {\"ping\": \"pong\"}\n" 91 | ] 92 | } 93 | ], 94 | "source": [ 95 | "ping:" 96 | ] 97 | }, 98 | { 99 | "cell_type": "code", 100 | "execution_count": null, 101 | "metadata": {}, 102 | "outputs": [], 103 | "source": [] 104 | } 105 | ], 106 | "metadata": { 107 | "kernelspec": { 108 | "display_name": "Ansible", 109 | "language": "ansible", 110 | "name": "ansible" 111 | }, 112 | "language_info": { 113 | "codemirror_mode": "yaml", 114 | "file_extension": ".yml", 115 | "mimetype": "text/yaml", 116 | "name": "ansible" 117 | } 118 | }, 119 | "nbformat": 4, 120 | "nbformat_minor": 2 121 | } 122 | -------------------------------------------------------------------------------- /notebooks/HelloWorldPlaybookWithTemplate.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "metadata": {}, 7 | "outputs": [], 8 | "source": [ 9 | "#ansible.cfg\n", 10 | "[defaults]\n", 11 | "host_key_checking=False" 12 | ] 13 | }, 14 | { 15 | "cell_type": "code", 16 | "execution_count": 2, 17 | "metadata": {}, 18 | "outputs": [], 19 | "source": [ 20 | "#inventory\n", 21 | "[all]\n", 22 | "localhost ansible_connection=local" 23 | ] 24 | }, 25 | { 26 | "cell_type": "code", 27 | "execution_count": 3, 28 | "metadata": {}, 29 | "outputs": [], 30 | "source": [ 31 | "#vars example_vars\n", 32 | "message: hello from template" 33 | ] 34 | }, 35 | { 36 | "cell_type": "code", 37 | "execution_count": 4, 38 | "metadata": {}, 39 | "outputs": [], 40 | "source": [ 41 | "#template hello.j2\n", 42 | "{{message}} " 43 | ] 44 | }, 45 | { 46 | "cell_type": "code", 47 | "execution_count": 5, 48 | "metadata": {}, 49 | "outputs": [ 50 | { 51 | "name": "stdout", 52 | "output_type": "stream", 53 | "text": [ 54 | "\n" 55 | ] 56 | } 57 | ], 58 | "source": [ 59 | "#play\n", 60 | "name: hello world\n", 61 | "hosts: localhost\n", 62 | "gather_facts: false\n", 63 | "vars_files:\n", 64 | " - example_vars" 65 | ] 66 | }, 67 | { 68 | "cell_type": "code", 69 | "execution_count": 6, 70 | "metadata": {}, 71 | "outputs": [ 72 | { 73 | "name": "stdout", 74 | "output_type": "stream", 75 | "text": [ 76 | "TASK [template] ****************************************************************\n", 77 | "ok: [localhost] => {\"checksum\": \"0a82a60ff55d93919952ab6faeb2b024d3120584\", \"dest\": \"/tmp/hello\", \"gid\": 20, \"group\": \"staff\", \"mode\": \"0644\", \"owner\": \"bthomass\", \"path\": \"/tmp/hello\", \"size\": 19, \"state\": \"file\", \"uid\": 501}\n" 78 | ] 79 | } 80 | ], 81 | "source": [ 82 | "template:\n", 83 | " src: hello.j2\n", 84 | " dest: /tmp/hello" 85 | ] 86 | }, 87 | { 88 | "cell_type": "code", 89 | "execution_count": 7, 90 | "metadata": {}, 91 | "outputs": [ 92 | { 93 | "name": "stdout", 94 | "output_type": "stream", 95 | "text": [ 96 | "TASK [shell] *******************************************************************\n", 97 | "changed: [localhost] => {\"cmd\": \"cat /tmp/hello\", \"delta\": \"0:00:00.008952\", \"end\": \"2018-07-07 06:13:13.621259\", \"rc\": 0, \"start\": \"2018-07-07 06:13:13.612307\", \"stderr\": \"\", \"stderr_lines\": [], \"stdout\": \"hello from template\", \"stdout_lines\": [\"hello from template\"]}\n" 98 | ] 99 | } 100 | ], 101 | "source": [ 102 | "shell: cat /tmp/hello\n", 103 | "register: output" 104 | ] 105 | }, 106 | { 107 | "cell_type": "code", 108 | "execution_count": 8, 109 | "metadata": {}, 110 | "outputs": [ 111 | { 112 | "name": "stdout", 113 | "output_type": "stream", 114 | "text": [ 115 | "TASK [debug] *******************************************************************\n", 116 | "ok: [localhost] => {\n", 117 | " \"output.stdout\": \"hello from template\"\n", 118 | "}\n" 119 | ] 120 | } 121 | ], 122 | "source": [ 123 | "debug:\n", 124 | " var: output.stdout" 125 | ] 126 | }, 127 | { 128 | "cell_type": "code", 129 | "execution_count": null, 130 | "metadata": {}, 131 | "outputs": [], 132 | "source": [] 133 | } 134 | ], 135 | "metadata": { 136 | "kernelspec": { 137 | "display_name": "Ansible", 138 | "language": "ansible", 139 | "name": "ansible" 140 | }, 141 | "language_info": { 142 | "codemirror_mode": "yaml", 143 | "file_extension": ".yml", 144 | "mimetype": "text/yaml", 145 | "name": "ansible" 146 | } 147 | }, 148 | "nbformat": 4, 149 | "nbformat_minor": 2 150 | } 151 | -------------------------------------------------------------------------------- /notebooks/HelloWorldPlaybookWithVarsFile.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "metadata": {}, 7 | "outputs": [], 8 | "source": [ 9 | "#ansible.cfg\n", 10 | "[defaults]\n", 11 | "host_key_checking=False" 12 | ] 13 | }, 14 | { 15 | "cell_type": "code", 16 | "execution_count": 2, 17 | "metadata": {}, 18 | "outputs": [], 19 | "source": [ 20 | "#inventory\n", 21 | "[all]\n", 22 | "localhost ansible_connection=local" 23 | ] 24 | }, 25 | { 26 | "cell_type": "code", 27 | "execution_count": 3, 28 | "metadata": {}, 29 | "outputs": [], 30 | "source": [ 31 | "#vars example_vars\n", 32 | "message: hello vars" 33 | ] 34 | }, 35 | { 36 | "cell_type": "code", 37 | "execution_count": 4, 38 | "metadata": {}, 39 | "outputs": [ 40 | { 41 | "name": "stdout", 42 | "output_type": "stream", 43 | "text": [] 44 | } 45 | ], 46 | "source": [ 47 | "#play\n", 48 | "name: hello world\n", 49 | "hosts: localhost\n", 50 | "gather_facts: false\n", 51 | "vars_files:\n", 52 | " - example_vars" 53 | ] 54 | }, 55 | { 56 | "cell_type": "code", 57 | "execution_count": 5, 58 | "metadata": {}, 59 | "outputs": [ 60 | { 61 | "name": "stdout", 62 | "output_type": "stream", 63 | "text": [ 64 | "TASK [debug] *******************************************************************\n", 65 | "ok: [localhost] => {\n", 66 | " \"msg\": \"hello vars\"\n", 67 | "}\n" 68 | ] 69 | } 70 | ], 71 | "source": [ 72 | "#task\n", 73 | "debug:\n", 74 | " msg: \"{{message}}\"" 75 | ] 76 | }, 77 | { 78 | "cell_type": "code", 79 | "execution_count": null, 80 | "metadata": {}, 81 | "outputs": [], 82 | "source": [] 83 | } 84 | ], 85 | "metadata": { 86 | "kernelspec": { 87 | "display_name": "Ansible", 88 | "language": "ansible", 89 | "name": "ansible" 90 | }, 91 | "language_info": { 92 | "codemirror_mode": "yaml", 93 | "file_extension": ".yml", 94 | "mimetype": "text/yaml", 95 | "name": "ansible" 96 | } 97 | }, 98 | "nbformat": 4, 99 | "nbformat_minor": 2 100 | } 101 | -------------------------------------------------------------------------------- /notebooks/HelloWorldPython.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# HelloWorldPython\n", 8 | "\n", 9 | "Variables registered by tasks in Ansible are available from `#python` cells" 10 | ] 11 | }, 12 | { 13 | "cell_type": "code", 14 | "execution_count": 1, 15 | "metadata": {}, 16 | "outputs": [ 17 | { 18 | "name": "stdout", 19 | "output_type": "stream", 20 | "text": [ 21 | "TASK [debug] *******************************************************************\n", 22 | "ok: [localhost] => {\n", 23 | " \"msg\": \"Hello world!\"\n", 24 | "}\n" 25 | ] 26 | } 27 | ], 28 | "source": [ 29 | "debug:\n", 30 | "register: output1" 31 | ] 32 | }, 33 | { 34 | "cell_type": "code", 35 | "execution_count": 2, 36 | "metadata": {}, 37 | "outputs": [ 38 | { 39 | "name": "stdout", 40 | "output_type": "stream", 41 | "text": [ 42 | "{'localhost': {u'msg': u'Hello world!', u'changed': False, u'_ansible_verbose_always': True, u'_ansible_no_log': False}}\n" 43 | ] 44 | } 45 | ], 46 | "source": [ 47 | "#python\n", 48 | "print (output1)" 49 | ] 50 | }, 51 | { 52 | "cell_type": "code", 53 | "execution_count": 3, 54 | "metadata": {}, 55 | "outputs": [ 56 | { 57 | "name": "stdout", 58 | "output_type": "stream", 59 | "text": [ 60 | "TASK [shell] *******************************************************************\n", 61 | "changed: [localhost] => {\n", 62 | " \"cmd\": \"ls\", \n", 63 | " \"delta\": \"0:00:00.007512\", \n", 64 | " \"end\": \"2018-11-30 09:32:59.642743\", \n", 65 | " \"rc\": 0, \n", 66 | " \"start\": \"2018-11-30 09:32:59.635231\", \n", 67 | " \"stderr\": \"\", \n", 68 | " \"stderr_lines\": [], \n", 69 | " \"stdout\": \"[see below]\", \n", 70 | " \"stdout_lines\": \"[removed for clarity]\"\n", 71 | "}\n", 72 | "\n", 73 | "[localhost] stdout:\n", 74 | "ansible.cfg\n", 75 | "next_task0.yml\n", 76 | "next_task1.yml\n", 77 | "next_task2.yml\n", 78 | "playbook.yml\n", 79 | "roles\n", 80 | "widget_vars.yml\n" 81 | ] 82 | } 83 | ], 84 | "source": [ 85 | "shell: ls\n", 86 | "register: output2" 87 | ] 88 | }, 89 | { 90 | "cell_type": "code", 91 | "execution_count": 4, 92 | "metadata": {}, 93 | "outputs": [ 94 | { 95 | "name": "stdout", 96 | "output_type": "stream", 97 | "text": [ 98 | "{'localhost': {u'_ansible_no_log': False,\n", 99 | " u'_ansible_parsed': True,\n", 100 | " u'changed': True,\n", 101 | " u'cmd': u'ls',\n", 102 | " u'delta': u'0:00:00.007512',\n", 103 | " u'end': u'2018-11-30 09:32:59.642743',\n", 104 | " u'invocation': {u'module_args': {u'_raw_params': u'ls',\n", 105 | " u'_uses_shell': True,\n", 106 | " u'argv': None,\n", 107 | " u'chdir': None,\n", 108 | " u'creates': None,\n", 109 | " u'executable': None,\n", 110 | " u'removes': None,\n", 111 | " u'stdin': None,\n", 112 | " u'warn': True}},\n", 113 | " u'rc': 0,\n", 114 | " u'start': u'2018-11-30 09:32:59.635231',\n", 115 | " u'stderr': u'',\n", 116 | " u'stderr_lines': [],\n", 117 | " u'stdout': u'ansible.cfg\\nnext_task0.yml\\nnext_task1.yml\\nnext_task2.yml\\nplaybook.yml\\nroles\\nwidget_vars.yml',\n", 118 | " u'stdout_lines': [u'ansible.cfg',\n", 119 | " u'next_task0.yml',\n", 120 | " u'next_task1.yml',\n", 121 | " u'next_task2.yml',\n", 122 | " u'playbook.yml',\n", 123 | " u'roles',\n", 124 | " u'widget_vars.yml']}}\n" 125 | ] 126 | } 127 | ], 128 | "source": [ 129 | "#python\n", 130 | "from pprint import pprint\n", 131 | "pprint (output2)" 132 | ] 133 | }, 134 | { 135 | "cell_type": "code", 136 | "execution_count": null, 137 | "metadata": {}, 138 | "outputs": [], 139 | "source": [] 140 | } 141 | ], 142 | "metadata": { 143 | "kernelspec": { 144 | "display_name": "Ansible", 145 | "language": "ansible", 146 | "name": "ansible" 147 | }, 148 | "language_info": { 149 | "codemirror_mode": "yaml", 150 | "file_extension": ".yml", 151 | "mimetype": "text/yaml", 152 | "name": "ansible" 153 | } 154 | }, 155 | "nbformat": 4, 156 | "nbformat_minor": 2 157 | } 158 | -------------------------------------------------------------------------------- /notebooks/HelloWorldPythonVariables.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# HelloWorldPythonVariables\n", 8 | "\n", 9 | "Global variables in the `#python` cells are available as facts in `#task` cells." 10 | ] 11 | }, 12 | { 13 | "cell_type": "code", 14 | "execution_count": 5, 15 | "metadata": {}, 16 | "outputs": [], 17 | "source": [ 18 | "#python\n", 19 | "x = 'Hello from Python'" 20 | ] 21 | }, 22 | { 23 | "cell_type": "code", 24 | "execution_count": 6, 25 | "metadata": {}, 26 | "outputs": [ 27 | { 28 | "name": "stdout", 29 | "output_type": "stream", 30 | "text": [ 31 | "TASK [debug] *******************************************************************\n", 32 | "ok: [localhost] => {\n", 33 | " \"x\": \"Hello from Python\"\n", 34 | "}\n" 35 | ] 36 | } 37 | ], 38 | "source": [ 39 | "debug:\n", 40 | " var: x" 41 | ] 42 | }, 43 | { 44 | "cell_type": "code", 45 | "execution_count": null, 46 | "metadata": {}, 47 | "outputs": [], 48 | "source": [] 49 | } 50 | ], 51 | "metadata": { 52 | "kernelspec": { 53 | "display_name": "Ansible", 54 | "language": "ansible", 55 | "name": "ansible" 56 | }, 57 | "language_info": { 58 | "codemirror_mode": "yaml", 59 | "file_extension": ".yml", 60 | "mimetype": "text/yaml", 61 | "name": "ansible" 62 | } 63 | }, 64 | "nbformat": 4, 65 | "nbformat_minor": 2 66 | } 67 | -------------------------------------------------------------------------------- /notebooks/HelloWorldRoles.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Includes a role in a play using the roles list" 8 | ] 9 | }, 10 | { 11 | "cell_type": "code", 12 | "execution_count": 1, 13 | "metadata": {}, 14 | "outputs": [], 15 | "source": [ 16 | "#ansible.cfg\n", 17 | "[defaults]\n", 18 | "roles_path=roles" 19 | ] 20 | }, 21 | { 22 | "cell_type": "code", 23 | "execution_count": 2, 24 | "metadata": {}, 25 | "outputs": [ 26 | { 27 | "name": "stdout", 28 | "output_type": "stream", 29 | "text": [ 30 | "\n", 31 | "TASK [hello : debug] ***********************************************************\n", 32 | "ok: [localhost] => {\n", 33 | " \"msg\": \"Hello world!\"\n", 34 | "}\n" 35 | ] 36 | } 37 | ], 38 | "source": [ 39 | "#play\n", 40 | "hosts: localhost\n", 41 | "gather_facts: false\n", 42 | "roles:\n", 43 | " - hello" 44 | ] 45 | }, 46 | { 47 | "cell_type": "code", 48 | "execution_count": null, 49 | "metadata": {}, 50 | "outputs": [], 51 | "source": [] 52 | } 53 | ], 54 | "metadata": { 55 | "kernelspec": { 56 | "display_name": "Ansible", 57 | "language": "ansible", 58 | "name": "ansible" 59 | }, 60 | "language_info": { 61 | "codemirror_mode": "yaml", 62 | "file_extension": ".yml", 63 | "mimetype": "text/yaml", 64 | "name": "ansible" 65 | } 66 | }, 67 | "nbformat": 4, 68 | "nbformat_minor": 2 69 | } 70 | -------------------------------------------------------------------------------- /notebooks/HelloWorldVault.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# HelloWorldVault\n", 8 | "\n", 9 | "Uses the #vault_password cell to bring up a password prompt. Type `1234` into the password field to decrypt the vault in `group_vars all`. " 10 | ] 11 | }, 12 | { 13 | "cell_type": "code", 14 | "execution_count": 2, 15 | "metadata": { 16 | "scrolled": true 17 | }, 18 | "outputs": [ 19 | { 20 | "data": { 21 | "application/vnd.jupyter.widget-view+json": { 22 | "model_id": "91d82bfaaae14881a73f696482e56186", 23 | "version_major": 2, 24 | "version_minor": 0 25 | }, 26 | "text/plain": [ 27 | "VaultPassword(description=u'Vault Password:', style=DescriptionStyle(description_width=u'initial'))" 28 | ] 29 | }, 30 | "metadata": {}, 31 | "output_type": "display_data" 32 | } 33 | ], 34 | "source": [ 35 | "#vault_password" 36 | ] 37 | }, 38 | { 39 | "cell_type": "code", 40 | "execution_count": 6, 41 | "metadata": {}, 42 | "outputs": [], 43 | "source": [ 44 | "#group_vars all\n", 45 | "$ANSIBLE_VAULT;1.1;AES256\n", 46 | "37646330646364396432363835663638396239313336633737646436313131316366653163636561\n", 47 | "3432613265663038626138366234363434623863663030340a663262323764313264353238396235\n", 48 | "39316432646636376238386563323331396564663135666430363935303030383733623262363665\n", 49 | "3134333132313337300a616463623664313636346337313235306638653637373037636637646663\n", 50 | "64303661663061356437616634366636656166626466393661313065303731616331" 51 | ] 52 | }, 53 | { 54 | "cell_type": "code", 55 | "execution_count": 7, 56 | "metadata": {}, 57 | "outputs": [ 58 | { 59 | "name": "stdout", 60 | "output_type": "stream", 61 | "text": [ 62 | "\n" 63 | ] 64 | } 65 | ], 66 | "source": [ 67 | "#play\n", 68 | "name: hello_world_vault\n", 69 | "hosts: localhost\n", 70 | "gather_facts: false" 71 | ] 72 | }, 73 | { 74 | "cell_type": "code", 75 | "execution_count": 8, 76 | "metadata": {}, 77 | "outputs": [ 78 | { 79 | "name": "stdout", 80 | "output_type": "stream", 81 | "text": [ 82 | "TASK [debug] *******************************************************************\n", 83 | "ok: [localhost] => {\n", 84 | " \"msg\": \"Hello World!\"\n", 85 | "}\n" 86 | ] 87 | } 88 | ], 89 | "source": [ 90 | "debug:\n", 91 | " var: msg" 92 | ] 93 | }, 94 | { 95 | "cell_type": "code", 96 | "execution_count": null, 97 | "metadata": {}, 98 | "outputs": [], 99 | "source": [] 100 | } 101 | ], 102 | "metadata": { 103 | "kernelspec": { 104 | "display_name": "Ansible", 105 | "language": "ansible", 106 | "name": "ansible" 107 | }, 108 | "language_info": { 109 | "codemirror_mode": "yaml", 110 | "file_extension": ".yml", 111 | "mimetype": "text/yaml", 112 | "name": "ansible" 113 | } 114 | }, 115 | "nbformat": 4, 116 | "nbformat_minor": 2 117 | } 118 | -------------------------------------------------------------------------------- /notebooks/roles/hello/meta/main.yml: -------------------------------------------------------------------------------- 1 | galaxy_info: 2 | author: Ben Thomasson 3 | description: Hello World role 4 | company: Red Hat 5 | 6 | license: Apache 7 | 8 | min_ansible_version: 1.2 9 | 10 | galaxy_tags: 11 | - hello 12 | dependencies: [] 13 | -------------------------------------------------------------------------------- /notebooks/roles/hello/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - debug: 3 | -------------------------------------------------------------------------------- /notebooks/templates/hello.j2: -------------------------------------------------------------------------------- 1 |

Hello {{target}}

2 | -------------------------------------------------------------------------------- /notebooks/vyos_backup.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# VyOS Back-up Example\n", 8 | "\n", 9 | "* Defines an ansible.cfg with host key checking off and a vault password file\n", 10 | "* Defines an inventory with leafs, spines, and servers\n", 11 | "* Defines an Ansible vault containing the password for the hosts protected by the vault password: 1234\n", 12 | "* Defines a play and task to backup the configuration of the switches" 13 | ] 14 | }, 15 | { 16 | "cell_type": "markdown", 17 | "metadata": {}, 18 | "source": [ 19 | "The contents of `~/.rhv/vault-secret` should be `1234`" 20 | ] 21 | }, 22 | { 23 | "cell_type": "code", 24 | "execution_count": 1, 25 | "metadata": {}, 26 | "outputs": [], 27 | "source": [ 28 | "#ansible.cfg\n", 29 | "[defaults]\n", 30 | "host_key_checking = False\n", 31 | "vault_password_file = ~/.rhv/vault-secret" 32 | ] 33 | }, 34 | { 35 | "cell_type": "code", 36 | "execution_count": 2, 37 | "metadata": {}, 38 | "outputs": [], 39 | "source": [ 40 | "#inventory\n", 41 | "[leafs]\n", 42 | "\n", 43 | "leaf00\n", 44 | "leaf01\n", 45 | "\n", 46 | "[spines]\n", 47 | "\n", 48 | "spine00\n", 49 | "spine01 \n", 50 | "\n", 51 | "[servers]\n", 52 | "\n", 53 | "server00\n", 54 | "server01\n", 55 | "\n", 56 | "[switches:children]\n", 57 | "\n", 58 | "leafs\n", 59 | "spines\n" 60 | ] 61 | }, 62 | { 63 | "cell_type": "code", 64 | "execution_count": 3, 65 | "metadata": {}, 66 | "outputs": [], 67 | "source": [ 68 | "#group_vars all\n", 69 | "$ANSIBLE_VAULT;1.1;AES256\n", 70 | "65656531623038643432386262366564646137356465323632386236633865656138316465326431\n", 71 | "6439613865626533333530323664653263663265313137340a316135313364646263633761623338\n", 72 | "62336565646635613764326566616637383464396435343966653561363765663430393461303561\n", 73 | "3862386430316136300a663837333836656166306132323535373762666335376230646537323163\n", 74 | "63653230303336306535653066346231326265393637306565323262376338633935" 75 | ] 76 | }, 77 | { 78 | "cell_type": "code", 79 | "execution_count": 4, 80 | "metadata": {}, 81 | "outputs": [], 82 | "source": [ 83 | "#group_vars switches\n", 84 | "ansible_network_os: vyos" 85 | ] 86 | }, 87 | { 88 | "cell_type": "code", 89 | "execution_count": 5, 90 | "metadata": {}, 91 | "outputs": [ 92 | { 93 | "name": "stdout", 94 | "output_type": "stream", 95 | "text": [] 96 | } 97 | ], 98 | "source": [ 99 | "#play\n", 100 | "name: two_by_two_with_hosts\n", 101 | "hosts: switches\n", 102 | "gather_facts: false\n", 103 | "connection: network_cli" 104 | ] 105 | }, 106 | { 107 | "cell_type": "code", 108 | "execution_count": 6, 109 | "metadata": {}, 110 | "outputs": [ 111 | { 112 | "name": "stdout", 113 | "output_type": "stream", 114 | "text": [ 115 | "TASK [vyos_config] *************************************************************\n", 116 | "ok: [spine00] => {\n", 117 | " \"backup_path\": \"/private/var/folders/p8/mttm7w913kq_v0wyfl9khlpc0000gn/T/ansible_kernel_playbookZu86In/backup/spine00_config.2018-06-26@13:43:01\", \n", 118 | " \"changed\": false, \n", 119 | " \"invocation\": {\n", 120 | " \"module_args\": {\n", 121 | " \"backup\": true, \n", 122 | " \"comment\": \"configured by vyos_config\", \n", 123 | " \"config\": null, \n", 124 | " \"host\": null, \n", 125 | " \"lines\": null, \n", 126 | " \"match\": \"line\", \n", 127 | " \"password\": null, \n", 128 | " \"port\": null, \n", 129 | " \"provider\": null, \n", 130 | " \"save\": false, \n", 131 | " \"src\": null, \n", 132 | " \"ssh_keyfile\": null, \n", 133 | " \"timeout\": null, \n", 134 | " \"username\": null\n", 135 | " }\n", 136 | " }\n", 137 | "}\n", 138 | "ok: [spine01] => {\n", 139 | " \"backup_path\": \"/private/var/folders/p8/mttm7w913kq_v0wyfl9khlpc0000gn/T/ansible_kernel_playbookZu86In/backup/spine01_config.2018-06-26@13:43:01\", \n", 140 | " \"changed\": false, \n", 141 | " \"invocation\": {\n", 142 | " \"module_args\": {\n", 143 | " \"backup\": true, \n", 144 | " \"comment\": \"configured by vyos_config\", \n", 145 | " \"config\": null, \n", 146 | " \"host\": null, \n", 147 | " \"lines\": null, \n", 148 | " \"match\": \"line\", \n", 149 | " \"password\": null, \n", 150 | " \"port\": null, \n", 151 | " \"provider\": null, \n", 152 | " \"save\": false, \n", 153 | " \"src\": null, \n", 154 | " \"ssh_keyfile\": null, \n", 155 | " \"timeout\": null, \n", 156 | " \"username\": null\n", 157 | " }\n", 158 | " }\n", 159 | "}\n", 160 | "ok: [leaf01] => {\n", 161 | " \"backup_path\": \"/private/var/folders/p8/mttm7w913kq_v0wyfl9khlpc0000gn/T/ansible_kernel_playbookZu86In/backup/leaf01_config.2018-06-26@13:43:02\", \n", 162 | " \"changed\": false, \n", 163 | " \"invocation\": {\n", 164 | " \"module_args\": {\n", 165 | " \"backup\": true, \n", 166 | " \"comment\": \"configured by vyos_config\", \n", 167 | " \"config\": null, \n", 168 | " \"host\": null, \n", 169 | " \"lines\": null, \n", 170 | " \"match\": \"line\", \n", 171 | " \"password\": null, \n", 172 | " \"port\": null, \n", 173 | " \"provider\": null, \n", 174 | " \"save\": false, \n", 175 | " \"src\": null, \n", 176 | " \"ssh_keyfile\": null, \n", 177 | " \"timeout\": null, \n", 178 | " \"username\": null\n", 179 | " }\n", 180 | " }\n", 181 | "}\n", 182 | "ok: [leaf00] => {\n", 183 | " \"backup_path\": \"/private/var/folders/p8/mttm7w913kq_v0wyfl9khlpc0000gn/T/ansible_kernel_playbookZu86In/backup/leaf00_config.2018-06-26@13:43:02\", \n", 184 | " \"changed\": false, \n", 185 | " \"invocation\": {\n", 186 | " \"module_args\": {\n", 187 | " \"backup\": true, \n", 188 | " \"comment\": \"configured by vyos_config\", \n", 189 | " \"config\": null, \n", 190 | " \"host\": null, \n", 191 | " \"lines\": null, \n", 192 | " \"match\": \"line\", \n", 193 | " \"password\": null, \n", 194 | " \"port\": null, \n", 195 | " \"provider\": null, \n", 196 | " \"save\": false, \n", 197 | " \"src\": null, \n", 198 | " \"ssh_keyfile\": null, \n", 199 | " \"timeout\": null, \n", 200 | " \"username\": null\n", 201 | " }\n", 202 | " }\n", 203 | "}\n" 204 | ] 205 | } 206 | ], 207 | "source": [ 208 | "#task\n", 209 | "vyos_config:\n", 210 | " backup: yes" 211 | ] 212 | }, 213 | { 214 | "cell_type": "code", 215 | "execution_count": null, 216 | "metadata": {}, 217 | "outputs": [], 218 | "source": [] 219 | } 220 | ], 221 | "metadata": { 222 | "kernelspec": { 223 | "display_name": "Ansible", 224 | "language": "ansible", 225 | "name": "ansible" 226 | }, 227 | "language_info": { 228 | "codemirror_mode": "yaml", 229 | "file_extension": ".yml", 230 | "mimetype": "text/yaml", 231 | "name": "ansible" 232 | } 233 | }, 234 | "nbformat": 4, 235 | "nbformat_minor": 2 236 | } 237 | -------------------------------------------------------------------------------- /openshift/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM fedora:29 2 | 3 | RUN dnf install -y python2-ipykernel python2-jupyter-core gcc python2-devel \ 4 | bzip2 openssh openssh-clients python2-crypto python2-psutil glibc-locale-source && \ 5 | localedef -c -i en_US -f UTF-8 en_US.UTF-8 && \ 6 | pip install --no-cache-dir wheel psutil && \ 7 | rm -rf /var/cache/yum 8 | 9 | ENV LANG=en_US.UTF-8 \ 10 | LANGUAGE=en_US:en \ 11 | LC_ALL=en_US.UTF-8 12 | 13 | ENV NB_USER notebook 14 | ENV NB_UID 10001 15 | 16 | ENV APP_ROOT=/opt/app-root 17 | ENV HOME=${APP_ROOT} 18 | ENV USER_NAME=${NB_USER} 19 | 20 | ENV PATH=${APP_ROOT}/bin:${PATH} 21 | COPY bin/ ${APP_ROOT}/bin/ 22 | RUN chmod -R u+x ${APP_ROOT}/bin && \ 23 | chgrp -R 0 ${APP_ROOT} && \ 24 | chmod -R g=u ${APP_ROOT} /etc/passwd 25 | 26 | RUN pip install --no-cache-dir ansible_kernel && \ 27 | python -m ansible_kernel.install 28 | USER ${NB_UID} 29 | WORKDIR ${APP_ROOT} 30 | 31 | ENTRYPOINT [ "uid_entrypoint"] 32 | CMD run 33 | EXPOSE 8888 34 | -------------------------------------------------------------------------------- /openshift/Dockerfile.centos: -------------------------------------------------------------------------------- 1 | FROM centos:7 2 | 3 | # Install Ansible Jupyter Kernel 4 | RUN yum -y install epel-release && \ 5 | yum -y install ansible python-psutil python-pip bzip2 python-crypto openssh openssh-clients gcc python-devel.x86_64 && \ 6 | localedef -c -i en_US -f UTF-8 en_US.UTF-8 && \ 7 | pip install --no-cache-dir wheel psutil && \ 8 | rm -rf /var/cache/yum 9 | 10 | RUN pip install --no-cache-dir prompt-toolkit==1.0.15 11 | RUN pip install --no-cache-dir ipython==5.7 12 | RUN pip install --no-cache-dir ipykernel==4.10 13 | 14 | ENV LANG=en_US.UTF-8 \ 15 | LANGUAGE=en_US:en \ 16 | LC_ALL=en_US.UTF-8 17 | 18 | ENV NB_USER notebook 19 | ENV NB_UID 10001 20 | 21 | ENV APP_ROOT=/opt/app-root 22 | ENV HOME=${APP_ROOT} 23 | ENV USER_NAME=${NB_USER} 24 | 25 | ENV PATH=${APP_ROOT}/bin:${PATH} 26 | COPY bin/ ${APP_ROOT}/bin/ 27 | RUN chmod -R u+x ${APP_ROOT}/bin && \ 28 | chgrp -R 0 ${APP_ROOT} && \ 29 | chmod -R g=u ${APP_ROOT} /etc/passwd 30 | 31 | RUN pip install --no-cache-dir ansible_kernel && \ 32 | python -m ansible_kernel.install 33 | USER ${NB_UID} 34 | WORKDIR ${APP_ROOT} 35 | 36 | ENTRYPOINT [ "uid_entrypoint"] 37 | CMD run 38 | EXPOSE 8888 39 | -------------------------------------------------------------------------------- /openshift/README.md: -------------------------------------------------------------------------------- 1 | 2 | ## Deploying Ansible Jupyter on OpenShift 3 | 4 | Create a new project. 5 | ``` 6 | oc new-project kernel 7 | ``` 8 | 9 | Add the template to the project, 10 | 11 | ``` 12 | oc create -f https://raw.githubusercontent.com/ansible/ansible-jupyter-kernel/master/openshift/openshift-template.yaml 13 | ``` 14 | 15 | And finally deploy. 16 | 17 | ``` 18 | oc new-app --template ansible-jupyter-kernel 19 | ``` 20 | 21 | 22 | ## Retrieve the login token 23 | 24 | ``` 25 | oc logs -f dc/ansible-jupyter 26 | ``` 27 | 28 | ## Get the route 29 | 30 | ``` 31 | oc get route ansible-jupyter --template '{{ (index (.status.ingress) 0).host }}' 32 | ``` 33 | 34 | -------------------------------------------------------------------------------- /openshift/bin/run: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | id 3 | whoami 4 | 5 | jupyter-notebook --ip 0.0.0.0 6 | -------------------------------------------------------------------------------- /openshift/bin/uid_entrypoint: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | if ! whoami &> /dev/null; then 3 | if [ -w /etc/passwd ]; then 4 | echo "${USER_NAME:-default}:x:$(id -u):0:${USER_NAME:-default} user:${HOME}:/sbin/nologin" >> /etc/passwd 5 | fi 6 | fi 7 | exec "$@" 8 | -------------------------------------------------------------------------------- /openshift/openshift-template.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Template 3 | metadata: 4 | name: ansible-jupyter-kernel 5 | objects: 6 | - apiVersion: v1 7 | kind: ImageStream 8 | metadata: 9 | labels: 10 | build: ansible-jupyter 11 | name: ansible-jupyter 12 | - apiVersion: v1 13 | kind: ImageStream 14 | metadata: 15 | name: fedora 16 | - apiVersion: image.openshift.io/v1 17 | kind: ImageStreamTag 18 | metadata: 19 | name: fedora:29 20 | tag: 21 | from: 22 | kind: DockerImage 23 | name: fedora:29 24 | importPolicy: {} 25 | name: "29" 26 | referencePolicy: 27 | type: Source 28 | - apiVersion: v1 29 | kind: Service 30 | metadata: 31 | labels: 32 | app: ansible-jupyter 33 | name: ansible-jupyter 34 | spec: 35 | ports: 36 | - name: 8888-tcp 37 | port: 8888 38 | protocol: TCP 39 | targetPort: 8888 40 | selector: 41 | app: ansible-jupyter 42 | deploymentconfig: ansible-jupyter 43 | sessionAffinity: None 44 | type: ClusterIP 45 | - apiVersion: v1 46 | kind: DeploymentConfig 47 | metadata: 48 | labels: 49 | app: ansible-jupyter 50 | name: ansible-jupyter 51 | spec: 52 | replicas: 1 53 | selector: 54 | app: ansible-jupyter 55 | deploymentconfig: ansible-jupyter 56 | strategy: 57 | activeDeadlineSeconds: 21600 58 | resources: {} 59 | rollingParams: 60 | intervalSeconds: 1 61 | maxSurge: 25% 62 | maxUnavailable: 25% 63 | timeoutSeconds: 600 64 | updatePeriodSeconds: 1 65 | type: Rolling 66 | template: 67 | metadata: 68 | labels: 69 | app: ansible-jupyter 70 | deploymentconfig: ansible-jupyter 71 | spec: 72 | containers: 73 | - image: '' 74 | imagePullPolicy: Always 75 | name: ansible-jupyter 76 | ports: 77 | - containerPort: 8888 78 | protocol: TCP 79 | resources: {} 80 | terminationMessagePath: /dev/termination-log 81 | terminationMessagePolicy: File 82 | dnsPolicy: ClusterFirst 83 | restartPolicy: Always 84 | schedulerName: default-scheduler 85 | securityContext: {} 86 | terminationGracePeriodSeconds: 30 87 | test: false 88 | triggers: 89 | - type: ConfigChange 90 | - imageChangeParams: 91 | automatic: true 92 | containerNames: 93 | - ansible-jupyter 94 | from: 95 | kind: ImageStreamTag 96 | name: ansible-jupyter:latest 97 | type: ImageChange 98 | - apiVersion: v1 99 | kind: Route 100 | metadata: 101 | labels: 102 | app: ansible-jupyter 103 | name: ansible-jupyter 104 | spec: 105 | port: 106 | targetPort: 8888-tcp 107 | to: 108 | kind: Service 109 | name: ansible-jupyter 110 | weight: 100 111 | wildcardPolicy: None 112 | - apiVersion: v1 113 | kind: BuildConfig 114 | metadata: 115 | labels: 116 | build: ansible-jupyter 117 | name: ansible-jupyter 118 | spec: 119 | output: 120 | to: 121 | kind: ImageStreamTag 122 | name: ansible-jupyter:latest 123 | source: 124 | contextDir: openshift 125 | git: 126 | ref: "${SOURCE_REPOSITORY_REF}" 127 | uri: "${SOURCE_REPOSITORY_URL}" 128 | type: Git 129 | strategy: 130 | dockerStrategy: 131 | from: 132 | kind: ImageStreamTag 133 | name: fedora:29 134 | type: Docker 135 | triggers: 136 | - type: ConfigChange 137 | - imageChange: {} 138 | type: ImageChange 139 | parameters: 140 | - description: The URL of the repository with your application source code. 141 | displayName: Git Repository URL 142 | name: SOURCE_REPOSITORY_URL 143 | required: true 144 | value: https://github.com/ansible/ansible-jupyter-kernel 145 | - description: Set this to a branch name, tag or other ref of your repository if you 146 | are not using the default branch. 147 | displayName: Git Reference 148 | name: SOURCE_REPOSITORY_REF 149 | value: master 150 | 151 | -------------------------------------------------------------------------------- /setup.cfg: -------------------------------------------------------------------------------- 1 | [pep8] 2 | # E201 - Whitespace after '(' 3 | # E203 - Whitespace before ":" 4 | # E221 - Multiple spaces after operator 5 | # E225 - Missing whitespace around operator 6 | # E231 - Missing whitespace after ',' 7 | # E241 - Multiple spaces after ',' 8 | # E251 - Unexpected spaces around keyword / parameter equals 9 | # E261 - At least two spaces before inline comment 10 | # E302 - Expected 2 blank lines found 0 11 | # E303 - Too many blank lines 12 | # W291 - Trailing whitespace 13 | # W391 - Blank line at end of file 14 | # W293 - Blank line contains whitespace 15 | ignore=E201,E203,E221,E225,E231,E241,E251,E261,E265,E303,W291,W391,W293 16 | 17 | [flake8] 18 | max-line-length=160 19 | ignore=E201,E203,E221,E225,E231,E241,E251,E261,E265,E303,W291,W391,W293,E731,F405 20 | 21 | [metadata] 22 | license_file=LICENSE.md 23 | description-file = README.md -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | import json 2 | import os 3 | from setuptools import setup, find_packages 4 | from setuptools.command.install import install 5 | 6 | 7 | class Installer(install): 8 | def run(self): 9 | # Regular install 10 | install.run(self) 11 | 12 | # Post install 13 | print('Installing Ansible Kernel kernelspec') 14 | from jupyter_client.kernelspec import KernelSpecManager 15 | from IPython.utils.tempdir import TemporaryDirectory 16 | kernel_json = { 17 | "argv": ["python", "-m", "ansible_kernel", "-f", "{connection_file}"], 18 | "codemirror_mode": "yaml", 19 | "display_name": "Ansible", 20 | "language": "ansible" 21 | } 22 | with TemporaryDirectory() as td: 23 | os.chmod(td, 0o755) 24 | with open(os.path.join(td, 'kernel.json'), 'w') as f: 25 | json.dump(kernel_json, f, sort_keys=True) 26 | ksm = KernelSpecManager() 27 | ksm.install_kernel_spec(td, 'ansible', user=self.user, replace=True, prefix=self.prefix) 28 | 29 | 30 | setup( 31 | name='ansible-kernel', 32 | version='1.0.0', 33 | description='An Ansible kernel for Jupyter notebooks', 34 | long_description='An Ansible kernel for Jupyter notebooks', 35 | long_description_content_type='text/plain', 36 | packages=find_packages(), 37 | package_data={'ansible_kernel': ['templates/ansible_playbook.tpl', 38 | 'templates/ansible_tasks.tpl', 39 | 'modules.yml', 40 | 'module_args.yml']}, 41 | cmdclass={'install': Installer}, 42 | license='Apache', 43 | install_requires=[ 44 | 'ansible', 45 | 'ansible-runner>=1.1.0', 46 | 'PyYAML', 47 | 'psutil', 48 | 'jupyter', 49 | 'tqdm', 50 | 'docopt', 51 | 'six', 52 | 'ipywidgets', 53 | ], 54 | entry_points={ 55 | "nbconvert.exporters": [ 56 | 'ansible_tasks=ansible_kernel.exporters:AnsibleTasksExporter', 57 | 'ansible_playbook=ansible_kernel.exporters:AnsiblePlaybookExporter', 58 | 'ansible_zip=ansible_kernel.exporters:AnsibleZipExporter'] 59 | }, 60 | zip_safe=False 61 | ) 62 | -------------------------------------------------------------------------------- /tests/AllUnreachable.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Tests that a play continues with some unreachable hosts\n", 8 | "\n", 9 | "* Passes if debug command runs - PASS" 10 | ] 11 | }, 12 | { 13 | "cell_type": "code", 14 | "execution_count": 1, 15 | "metadata": {}, 16 | "outputs": [], 17 | "source": [ 18 | "#inventory\n", 19 | "unreachable_host\n", 20 | "unreachable_host2" 21 | ] 22 | }, 23 | { 24 | "cell_type": "code", 25 | "execution_count": 2, 26 | "metadata": {}, 27 | "outputs": [ 28 | { 29 | "name": "stdout", 30 | "output_type": "stream", 31 | "text": [] 32 | } 33 | ], 34 | "source": [ 35 | "#play\n", 36 | "name: unreachable test 2\n", 37 | "hosts: all\n", 38 | "gather_facts: false" 39 | ] 40 | }, 41 | { 42 | "cell_type": "code", 43 | "execution_count": 7, 44 | "metadata": {}, 45 | "outputs": [ 46 | { 47 | "name": "stdout", 48 | "output_type": "stream", 49 | "text": [ 50 | "TASK [ping] ********************************************************************\n", 51 | "fatal: [unreachable_host]: UNREACHABLE!\n", 52 | "fatal: [unreachable_host2]: UNREACHABLE!\n", 53 | "\n", 54 | "Playbook ended\n", 55 | "Context lost!\n" 56 | ] 57 | } 58 | ], 59 | "source": [ 60 | "ping:" 61 | ] 62 | }, 63 | { 64 | "cell_type": "code", 65 | "execution_count": 5, 66 | "metadata": {}, 67 | "outputs": [ 68 | { 69 | "name": "stdout", 70 | "output_type": "stream", 71 | "text": [ 72 | "TASK [debug] *******************************************************************\n", 73 | "ok: [unreachable_host] => {\n", 74 | " \"msg\": \"Hello world!\"\n", 75 | "}\n", 76 | "ok: [unreachable_host2] => {\n", 77 | " \"msg\": \"Hello world!\"\n", 78 | "}\n" 79 | ] 80 | } 81 | ], 82 | "source": [ 83 | "debug:" 84 | ] 85 | }, 86 | { 87 | "cell_type": "code", 88 | "execution_count": null, 89 | "metadata": {}, 90 | "outputs": [], 91 | "source": [] 92 | } 93 | ], 94 | "metadata": { 95 | "kernelspec": { 96 | "display_name": "Ansible", 97 | "language": "ansible", 98 | "name": "ansible" 99 | }, 100 | "language_info": { 101 | "codemirror_mode": "yaml", 102 | "file_extension": ".yml", 103 | "mimetype": "text/yaml", 104 | "name": "ansible" 105 | } 106 | }, 107 | "nbformat": 4, 108 | "nbformat_minor": 2 109 | } 110 | -------------------------------------------------------------------------------- /tests/AllUnreachableDebugOnly.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Tests that a play continues with some unreachable hosts\n", 8 | "\n", 9 | "* Passes if debug command runs - PASS\n" 10 | ] 11 | }, 12 | { 13 | "cell_type": "code", 14 | "execution_count": 4, 15 | "metadata": {}, 16 | "outputs": [], 17 | "source": [ 18 | "#inventory\n", 19 | "unreachable_host\n", 20 | "unreachable_host2" 21 | ] 22 | }, 23 | { 24 | "cell_type": "code", 25 | "execution_count": 7, 26 | "metadata": {}, 27 | "outputs": [ 28 | { 29 | "name": "stdout", 30 | "output_type": "stream", 31 | "text": [] 32 | } 33 | ], 34 | "source": [ 35 | "#play\n", 36 | "name: unreachable test 3\n", 37 | "hosts: all\n", 38 | "gather_facts: false" 39 | ] 40 | }, 41 | { 42 | "cell_type": "code", 43 | "execution_count": 8, 44 | "metadata": {}, 45 | "outputs": [ 46 | { 47 | "name": "stdout", 48 | "output_type": "stream", 49 | "text": [ 50 | "TASK [debug] *******************************************************************\n", 51 | "ok: [unreachable_host] => {\n", 52 | " \"msg\": \"Hello world!\"\n", 53 | "}\n", 54 | "ok: [unreachable_host2] => {\n", 55 | " \"msg\": \"Hello world!\"\n", 56 | "}\n" 57 | ] 58 | } 59 | ], 60 | "source": [ 61 | "debug:" 62 | ] 63 | }, 64 | { 65 | "cell_type": "code", 66 | "execution_count": null, 67 | "metadata": {}, 68 | "outputs": [], 69 | "source": [] 70 | }, 71 | { 72 | "cell_type": "code", 73 | "execution_count": null, 74 | "metadata": {}, 75 | "outputs": [], 76 | "source": [] 77 | } 78 | ], 79 | "metadata": { 80 | "kernelspec": { 81 | "display_name": "Ansible", 82 | "language": "ansible", 83 | "name": "ansible" 84 | }, 85 | "language_info": { 86 | "codemirror_mode": "yaml", 87 | "file_extension": ".yml", 88 | "mimetype": "text/yaml", 89 | "name": "ansible" 90 | } 91 | }, 92 | "nbformat": 4, 93 | "nbformat_minor": 2 94 | } 95 | -------------------------------------------------------------------------------- /tests/BadArguments.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Test bad arguments\n", 8 | "\n", 9 | "* Test passes if the ping command runs: PASS" 10 | ] 11 | }, 12 | { 13 | "cell_type": "code", 14 | "execution_count": 1, 15 | "metadata": {}, 16 | "outputs": [ 17 | { 18 | "name": "stdout", 19 | "output_type": "stream", 20 | "text": [ 21 | "TASK [debug] *******************************************************************\n", 22 | "fatal: [localhost]: FAILED! => {\n", 23 | " \"msg\": \"'dfdfdff' is not a valid option in debug\"\n", 24 | "}\n" 25 | ] 26 | } 27 | ], 28 | "source": [ 29 | "debug:\n", 30 | " dfdfdff:" 31 | ] 32 | }, 33 | { 34 | "cell_type": "code", 35 | "execution_count": 2, 36 | "metadata": {}, 37 | "outputs": [ 38 | { 39 | "name": "stdout", 40 | "output_type": "stream", 41 | "text": [ 42 | "TASK [ping] ********************************************************************\n" 43 | ] 44 | } 45 | ], 46 | "source": [ 47 | "ping:" 48 | ] 49 | }, 50 | { 51 | "cell_type": "code", 52 | "execution_count": null, 53 | "metadata": {}, 54 | "outputs": [], 55 | "source": [] 56 | } 57 | ], 58 | "metadata": { 59 | "kernelspec": { 60 | "display_name": "Ansible", 61 | "language": "ansible", 62 | "name": "ansible" 63 | }, 64 | "language_info": { 65 | "codemirror_mode": "yaml", 66 | "file_extension": ".yml", 67 | "mimetype": "text/yaml", 68 | "name": "ansible" 69 | } 70 | }, 71 | "nbformat": 4, 72 | "nbformat_minor": 2 73 | } 74 | -------------------------------------------------------------------------------- /tests/DefaultInventoryExport.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Tests Default Inventory Export\n", 8 | "\n", 9 | "* Passes if unarchived inventory export matches the expected file contents" 10 | ] 11 | }, 12 | { 13 | "cell_type": "code", 14 | "execution_count": null, 15 | "metadata": {}, 16 | "outputs": [], 17 | "source": [ 18 | "#play\n", 19 | "hosts: localhost\n", 20 | "connection: local\n", 21 | "gather_facts: no" 22 | ] 23 | }, 24 | { 25 | "cell_type": "code", 26 | "execution_count": null, 27 | "metadata": {}, 28 | "outputs": [], 29 | "source": [ 30 | "#task\n", 31 | "set_fact:\n", 32 | " expected_inventory: \"[all]\\nlocalhost ansible_connection=local\"\n", 33 | " exporter: ansible_kernel.exporters.ansible_zip.AnsibleZipExporter\n", 34 | " test_ipynb: |\n", 35 | " {\n", 36 | " \"cells\": [\n", 37 | " {\n", 38 | " \"cell_type\": \"markdown\",\n", 39 | " \"metadata\": {},\n", 40 | " \"source\": [\n", 41 | " \"# Tests that a simple task runs\\n\",\n", 42 | " \"\\n\",\n", 43 | " \"* Passes if the debug command runs - PASS\"\n", 44 | " ]\n", 45 | " },\n", 46 | " {\n", 47 | " \"cell_type\": \"code\",\n", 48 | " \"execution_count\": 1,\n", 49 | " \"metadata\": {},\n", 50 | " \"outputs\": [\n", 51 | " {\n", 52 | " \"name\": \"stdout\",\n", 53 | " \"output_type\": \"stream\",\n", 54 | " \"text\": [\n", 55 | " \"TASK [debug] *******************************************************************\\n\",\n", 56 | " \"ok: [localhost] => {\\n\",\n", 57 | " \" \\\"msg\\\": \\\"Hello world!\\\"\\n\",\n", 58 | " \"}\\n\"\n", 59 | " ]\n", 60 | " }\n", 61 | " ],\n", 62 | " \"source\": [\n", 63 | " \"debug:\"\n", 64 | " ]\n", 65 | " },\n", 66 | " {\n", 67 | " \"cell_type\": \"code\",\n", 68 | " \"execution_count\": null,\n", 69 | " \"metadata\": {},\n", 70 | " \"outputs\": [],\n", 71 | " \"source\": []\n", 72 | " }\n", 73 | " ],\n", 74 | " \"metadata\": {\n", 75 | " \"kernelspec\": {\n", 76 | " \"display_name\": \"Ansible\",\n", 77 | " \"language\": \"ansible\",\n", 78 | " \"name\": \"ansible\"\n", 79 | " },\n", 80 | " \"language_info\": {\n", 81 | " \"codemirror_mode\": \"yaml\",\n", 82 | " \"file_extension\": \".yml\",\n", 83 | " \"mimetype\": \"text/yaml\",\n", 84 | " \"name\": \"ansible\"\n", 85 | " }\n", 86 | " },\n", 87 | " \"nbformat\": 4,\n", 88 | " \"nbformat_minor\": 2\n", 89 | " }" 90 | ] 91 | }, 92 | { 93 | "cell_type": "code", 94 | "execution_count": null, 95 | "metadata": {}, 96 | "outputs": [], 97 | "source": [ 98 | "#task\n", 99 | "shell: pwd\n", 100 | "register: current_path_command" 101 | ] 102 | }, 103 | { 104 | "cell_type": "code", 105 | "execution_count": null, 106 | "metadata": {}, 107 | "outputs": [], 108 | "source": [ 109 | "#task\n", 110 | "set_fact: current_path={{ current_path_command.stdout }}" 111 | ] 112 | }, 113 | { 114 | "cell_type": "code", 115 | "execution_count": null, 116 | "metadata": {}, 117 | "outputs": [], 118 | "source": [ 119 | "#task\n", 120 | "name: create test file\n", 121 | "copy: content=\"{{ test_ipynb }}\" dest={{ current_path }}/test.ipynb" 122 | ] 123 | }, 124 | { 125 | "cell_type": "code", 126 | "execution_count": null, 127 | "metadata": {}, 128 | "outputs": [], 129 | "source": [ 130 | "#task\n", 131 | "name: run exporter\n", 132 | "shell: jupyter nbconvert --to {{ exporter }} {{ current_path }}/test.ipynb" 133 | ] 134 | }, 135 | { 136 | "cell_type": "code", 137 | "execution_count": null, 138 | "metadata": {}, 139 | "outputs": [], 140 | "source": [ 141 | "#task\n", 142 | "name: unarchive test zip\n", 143 | "unarchive:\n", 144 | " remote_src: yes\n", 145 | " src: '{{ current_path }}/test.zip'\n", 146 | " dest: '{{ current_path }}'" 147 | ] 148 | }, 149 | { 150 | "cell_type": "code", 151 | "execution_count": null, 152 | "metadata": {}, 153 | "outputs": [], 154 | "source": [ 155 | "#task\n", 156 | "name: read inventory\n", 157 | "slurp:\n", 158 | " src: '{{ current_path }}/inventory'\n", 159 | "register: inventory_file" 160 | ] 161 | }, 162 | { 163 | "cell_type": "code", 164 | "execution_count": null, 165 | "metadata": {}, 166 | "outputs": [], 167 | "source": [ 168 | "#task\n", 169 | "name: decode inventory\n", 170 | "set_fact: actual_inventory={{ inventory_file['content'] | b64decode }}" 171 | ] 172 | }, 173 | { 174 | "cell_type": "code", 175 | "execution_count": null, 176 | "metadata": {}, 177 | "outputs": [], 178 | "source": [ 179 | "#task\n", 180 | "name: check expected inventory content\n", 181 | "assert:\n", 182 | " that: actual_inventory == expected_inventory" 183 | ] 184 | }, 185 | { 186 | "cell_type": "code", 187 | "execution_count": null, 188 | "metadata": {}, 189 | "outputs": [], 190 | "source": [] 191 | } 192 | ], 193 | "metadata": { 194 | "kernelspec": { 195 | "display_name": "Ansible", 196 | "language": "ansible", 197 | "name": "ansible" 198 | }, 199 | "language_info": { 200 | "codemirror_mode": "yaml", 201 | "file_extension": ".yml", 202 | "mimetype": "text/yaml", 203 | "name": "ansible" 204 | } 205 | }, 206 | "nbformat": 4, 207 | "nbformat_minor": 2 208 | } 209 | -------------------------------------------------------------------------------- /tests/EmptyInventory.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Tests that an empty inventory is accepted\n", 8 | "\n", 9 | "* Test passes if the debug command runs - PASS" 10 | ] 11 | }, 12 | { 13 | "cell_type": "code", 14 | "execution_count": 1, 15 | "metadata": {}, 16 | "outputs": [], 17 | "source": [ 18 | "#inventory" 19 | ] 20 | }, 21 | { 22 | "cell_type": "code", 23 | "execution_count": 4, 24 | "metadata": {}, 25 | "outputs": [], 26 | "source": [ 27 | "#play\n", 28 | "hosts: localhost\n", 29 | "gather_facts: False" 30 | ] 31 | }, 32 | { 33 | "cell_type": "code", 34 | "execution_count": 5, 35 | "metadata": {}, 36 | "outputs": [ 37 | { 38 | "name": "stdout", 39 | "output_type": "stream", 40 | "text": [ 41 | "TASK [debug] *******************************************************************\n", 42 | "ok: [localhost] => {\n", 43 | " \"msg\": \"Hello world!\"\n", 44 | "}\n" 45 | ] 46 | } 47 | ], 48 | "source": [ 49 | "debug:" 50 | ] 51 | }, 52 | { 53 | "cell_type": "code", 54 | "execution_count": null, 55 | "metadata": {}, 56 | "outputs": [], 57 | "source": [] 58 | } 59 | ], 60 | "metadata": { 61 | "kernelspec": { 62 | "display_name": "Ansible", 63 | "language": "ansible", 64 | "name": "ansible" 65 | }, 66 | "language_info": { 67 | "codemirror_mode": "yaml", 68 | "file_extension": ".yml", 69 | "mimetype": "text/yaml", 70 | "name": "ansible" 71 | } 72 | }, 73 | "nbformat": 4, 74 | "nbformat_minor": 2 75 | } 76 | -------------------------------------------------------------------------------- /tests/EmptyPlay.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Tests that an empty pass raises an error\n", 8 | "\n", 9 | "* Passes if the play displays an error and play can be rerun - PASS" 10 | ] 11 | }, 12 | { 13 | "cell_type": "code", 14 | "execution_count": 7, 15 | "metadata": {}, 16 | "outputs": [ 17 | { 18 | "name": "stdout", 19 | "output_type": "stream", 20 | "text": [ 21 | "ERROR! the field 'hosts' is required but was not set\n" 22 | ] 23 | } 24 | ], 25 | "source": [ 26 | "#play" 27 | ] 28 | }, 29 | { 30 | "cell_type": "code", 31 | "execution_count": 8, 32 | "metadata": {}, 33 | "outputs": [ 34 | { 35 | "name": "stdout", 36 | "output_type": "stream", 37 | "text": [ 38 | "No play found. Run a valid play cell" 39 | ] 40 | } 41 | ], 42 | "source": [ 43 | "debug:" 44 | ] 45 | }, 46 | { 47 | "cell_type": "code", 48 | "execution_count": null, 49 | "metadata": {}, 50 | "outputs": [], 51 | "source": [] 52 | } 53 | ], 54 | "metadata": { 55 | "kernelspec": { 56 | "display_name": "Ansible", 57 | "language": "ansible", 58 | "name": "ansible" 59 | }, 60 | "language_info": { 61 | "codemirror_mode": "yaml", 62 | "file_extension": ".yml", 63 | "mimetype": "text/yaml", 64 | "name": "ansible" 65 | } 66 | }, 67 | "nbformat": 4, 68 | "nbformat_minor": 2 69 | } 70 | -------------------------------------------------------------------------------- /tests/EmptyTask.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Tests that an empty task cell is accepted\n", 8 | "\n", 9 | "* Test passes if the debug command runs - PASS" 10 | ] 11 | }, 12 | { 13 | "cell_type": "code", 14 | "execution_count": 4, 15 | "metadata": {}, 16 | "outputs": [], 17 | "source": [ 18 | "#task" 19 | ] 20 | }, 21 | { 22 | "cell_type": "code", 23 | "execution_count": 5, 24 | "metadata": {}, 25 | "outputs": [ 26 | { 27 | "name": "stdout", 28 | "output_type": "stream", 29 | "text": [ 30 | "TASK [debug] *******************************************************************\n", 31 | "ok: [localhost] => {\n", 32 | " \"msg\": \"Hello world!\"\n", 33 | "}\n" 34 | ] 35 | } 36 | ], 37 | "source": [ 38 | "debug:" 39 | ] 40 | }, 41 | { 42 | "cell_type": "code", 43 | "execution_count": null, 44 | "metadata": {}, 45 | "outputs": [], 46 | "source": [] 47 | }, 48 | { 49 | "cell_type": "code", 50 | "execution_count": null, 51 | "metadata": {}, 52 | "outputs": [], 53 | "source": [] 54 | } 55 | ], 56 | "metadata": { 57 | "kernelspec": { 58 | "display_name": "Ansible", 59 | "language": "ansible", 60 | "name": "ansible" 61 | }, 62 | "language_info": { 63 | "codemirror_mode": "yaml", 64 | "file_extension": ".yml", 65 | "mimetype": "text/yaml", 66 | "name": "ansible" 67 | } 68 | }, 69 | "nbformat": 4, 70 | "nbformat_minor": 2 71 | } 72 | -------------------------------------------------------------------------------- /tests/ExportAnsibleRegisteredVariables.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Tests that registered variables from `#task` cells are available to `#python` cells as global variables\n", 8 | "\n", 9 | "* PASS" 10 | ] 11 | }, 12 | { 13 | "cell_type": "code", 14 | "execution_count": 7, 15 | "metadata": {}, 16 | "outputs": [ 17 | { 18 | "name": "stdout", 19 | "output_type": "stream", 20 | "text": [ 21 | "TASK [debug] *******************************************************************\n", 22 | "ok: [localhost] => {\n", 23 | " \"msg\": \"Hello from Ansible\"\n", 24 | "}\n" 25 | ] 26 | } 27 | ], 28 | "source": [ 29 | "debug:\n", 30 | " msg: \"Hello from Ansible\"\n", 31 | "register: output" 32 | ] 33 | }, 34 | { 35 | "cell_type": "code", 36 | "execution_count": 8, 37 | "metadata": {}, 38 | "outputs": [], 39 | "source": [ 40 | "#python\n", 41 | "assert output['localhost']['msg'] == \"Hello from Ansible\"" 42 | ] 43 | }, 44 | { 45 | "cell_type": "code", 46 | "execution_count": null, 47 | "metadata": {}, 48 | "outputs": [], 49 | "source": [] 50 | } 51 | ], 52 | "metadata": { 53 | "kernelspec": { 54 | "display_name": "Ansible", 55 | "language": "ansible", 56 | "name": "ansible" 57 | }, 58 | "language_info": { 59 | "codemirror_mode": "yaml", 60 | "file_extension": ".yml", 61 | "mimetype": "text/yaml", 62 | "name": "ansible" 63 | } 64 | }, 65 | "nbformat": 4, 66 | "nbformat_minor": 2 67 | } 68 | -------------------------------------------------------------------------------- /tests/ExportPythonVariables.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Tests that global variables defined in the python scope are available as facts in ansible scope\n", 8 | "\n", 9 | "* Passes if x is defined in the ansible scope - PASS" 10 | ] 11 | }, 12 | { 13 | "cell_type": "code", 14 | "execution_count": 1, 15 | "metadata": {}, 16 | "outputs": [ 17 | { 18 | "data": { 19 | "text/plain": [ 20 | "5" 21 | ] 22 | }, 23 | "execution_count": 1, 24 | "metadata": {}, 25 | "output_type": "execute_result" 26 | } 27 | ], 28 | "source": [ 29 | "#python\n", 30 | "x = 5\n", 31 | "x" 32 | ] 33 | }, 34 | { 35 | "cell_type": "code", 36 | "execution_count": 3, 37 | "metadata": {}, 38 | "outputs": [ 39 | { 40 | "name": "stdout", 41 | "output_type": "stream", 42 | "text": [ 43 | "TASK [debug] *******************************************************************\n", 44 | "ok: [localhost] => {\n", 45 | " \"x\": 5\n", 46 | "}\n" 47 | ] 48 | } 49 | ], 50 | "source": [ 51 | "#task\n", 52 | "debug:\n", 53 | " var: x" 54 | ] 55 | }, 56 | { 57 | "cell_type": "code", 58 | "execution_count": 11, 59 | "metadata": {}, 60 | "outputs": [ 61 | { 62 | "name": "stdout", 63 | "output_type": "stream", 64 | "text": [ 65 | "TASK [assert] ******************************************************************\n", 66 | "ok: [localhost] => {\n", 67 | " \"msg\": \"All assertions passed\"\n", 68 | "}\n" 69 | ] 70 | } 71 | ], 72 | "source": [ 73 | "assert: \n", 74 | " that: x is defined" 75 | ] 76 | }, 77 | { 78 | "cell_type": "code", 79 | "execution_count": 12, 80 | "metadata": {}, 81 | "outputs": [ 82 | { 83 | "name": "stdout", 84 | "output_type": "stream", 85 | "text": [ 86 | "TASK [assert] ******************************************************************\n", 87 | "ok: [localhost] => {\n", 88 | " \"msg\": \"All assertions passed\"\n", 89 | "}\n" 90 | ] 91 | } 92 | ], 93 | "source": [ 94 | "assert: \n", 95 | " that: x == 5" 96 | ] 97 | }, 98 | { 99 | "cell_type": "code", 100 | "execution_count": null, 101 | "metadata": {}, 102 | "outputs": [], 103 | "source": [] 104 | } 105 | ], 106 | "metadata": { 107 | "kernelspec": { 108 | "display_name": "Ansible", 109 | "language": "ansible", 110 | "name": "ansible" 111 | }, 112 | "language_info": { 113 | "codemirror_mode": "yaml", 114 | "file_extension": ".yml", 115 | "mimetype": "text/yaml", 116 | "name": "ansible" 117 | } 118 | }, 119 | "nbformat": 4, 120 | "nbformat_minor": 2 121 | } 122 | -------------------------------------------------------------------------------- /tests/GalaxyRole.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Installs a galaxy role from and includes the role using the include_role module\n", 8 | "\n", 9 | "* This example includes the hello role in the playbook using include_role" 10 | ] 11 | }, 12 | { 13 | "cell_type": "code", 14 | "execution_count": 1, 15 | "metadata": {}, 16 | "outputs": [], 17 | "source": [ 18 | "#ansible.cfg\n", 19 | "[defaults]\n", 20 | "roles_path=roles" 21 | ] 22 | }, 23 | { 24 | "cell_type": "code", 25 | "execution_count": 2, 26 | "metadata": {}, 27 | "outputs": [ 28 | { 29 | "name": "stdout", 30 | "output_type": "stream", 31 | "text": [ 32 | "\n" 33 | ] 34 | } 35 | ], 36 | "source": [ 37 | "#play\n", 38 | "hosts: localhost\n", 39 | "gather_facts: false" 40 | ] 41 | }, 42 | { 43 | "cell_type": "code", 44 | "execution_count": 3, 45 | "metadata": {}, 46 | "outputs": [ 47 | { 48 | "name": "stdout", 49 | "output_type": "stream", 50 | "text": [ 51 | "- downloading role 'hello_role', owned by benthomasson\n", 52 | "- downloading role from https://github.com/benthomasson/hello-role/archive/master.tar.gz\n", 53 | "- extracting benthomasson.hello_role to /private/var/folders/p8/mttm7w913kq_v0wyfl9khlpc0000gn/T/ansible_kernel_playbookHZDwFO/roles/benthomasson.hello_role\n", 54 | "- benthomasson.hello_role (master) was installed successfully\n", 55 | "TASK [include_role : benthomasson.hello_role] **********************************\n", 56 | "TASK [benthomasson.hello_role : debug] *****************************************\n", 57 | "ok: [localhost] => {\n", 58 | " \"msg\": \"Hello world!\"\n", 59 | "}\n" 60 | ] 61 | } 62 | ], 63 | "source": [ 64 | "include_role:\n", 65 | " name: benthomasson.hello_role\n" 66 | ] 67 | }, 68 | { 69 | "cell_type": "code", 70 | "execution_count": null, 71 | "metadata": {}, 72 | "outputs": [], 73 | "source": [] 74 | }, 75 | { 76 | "cell_type": "code", 77 | "execution_count": null, 78 | "metadata": {}, 79 | "outputs": [], 80 | "source": [] 81 | } 82 | ], 83 | "metadata": { 84 | "kernelspec": { 85 | "display_name": "Ansible", 86 | "language": "ansible", 87 | "name": "ansible" 88 | }, 89 | "language_info": { 90 | "codemirror_mode": "yaml", 91 | "file_extension": ".yml", 92 | "mimetype": "text/yaml", 93 | "name": "ansible" 94 | } 95 | }, 96 | "nbformat": 4, 97 | "nbformat_minor": 2 98 | } 99 | -------------------------------------------------------------------------------- /tests/GalaxyRole2.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Installs a galaxy role from and includes the role using the include_role module\n", 8 | "\n", 9 | "* This example includes the hello role in the playbook using include_role" 10 | ] 11 | }, 12 | { 13 | "cell_type": "code", 14 | "execution_count": 1, 15 | "metadata": {}, 16 | "outputs": [], 17 | "source": [ 18 | "#ansible.cfg\n", 19 | "[defaults]\n", 20 | "roles_path=roles" 21 | ] 22 | }, 23 | { 24 | "cell_type": "code", 25 | "execution_count": 2, 26 | "metadata": {}, 27 | "outputs": [ 28 | { 29 | "name": "stdout", 30 | "output_type": "stream", 31 | "text": [ 32 | "\n" 33 | ] 34 | } 35 | ], 36 | "source": [ 37 | "#play\n", 38 | "hosts: localhost\n", 39 | "gather_facts: false" 40 | ] 41 | }, 42 | { 43 | "cell_type": "code", 44 | "execution_count": 3, 45 | "metadata": { 46 | "scrolled": true 47 | }, 48 | "outputs": [ 49 | { 50 | "name": "stdout", 51 | "output_type": "stream", 52 | "text": [ 53 | "- downloading role 'hello_role2', owned by benthomasson\n", 54 | "- downloading role from https://github.com/benthomasson/hello-role2/archive/master.tar.gz\n", 55 | "- extracting benthomasson.hello_role2 to /private/var/folders/p8/mttm7w913kq_v0wyfl9khlpc0000gn/T/ansible_kernel_playbookk_fkOd/roles/benthomasson.hello_role2\n", 56 | "- benthomasson.hello_role2 (master) was installed successfully\n", 57 | "TASK [include_role : benthomasson.hello_role2] *********************************\n", 58 | "TASK [benthomasson.hello_role2 : debug] ****************************************\n", 59 | "ok: [localhost] => {\n", 60 | " \"msg\": \"Hello world!\"\n", 61 | "}\n", 62 | "TASK [benthomasson.hello_role2 : debug] ****************************************\n", 63 | "ok: [localhost] => {\n", 64 | " \"msg\": \"Hello world!\"\n", 65 | "}\n" 66 | ] 67 | } 68 | ], 69 | "source": [ 70 | "include_role:\n", 71 | " name: benthomasson.hello_role2\n" 72 | ] 73 | }, 74 | { 75 | "cell_type": "code", 76 | "execution_count": null, 77 | "metadata": {}, 78 | "outputs": [], 79 | "source": [] 80 | }, 81 | { 82 | "cell_type": "code", 83 | "execution_count": null, 84 | "metadata": {}, 85 | "outputs": [], 86 | "source": [] 87 | } 88 | ], 89 | "metadata": { 90 | "kernelspec": { 91 | "display_name": "Ansible", 92 | "language": "ansible", 93 | "name": "ansible" 94 | }, 95 | "language_info": { 96 | "codemirror_mode": "yaml", 97 | "file_extension": ".yml", 98 | "mimetype": "text/yaml", 99 | "name": "ansible" 100 | } 101 | }, 102 | "nbformat": 4, 103 | "nbformat_minor": 2 104 | } 105 | -------------------------------------------------------------------------------- /tests/GalaxyRole3.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Installs a galaxy role from and includes the role using the include_role module\n", 8 | "\n", 9 | "* This example includes the hello role in the playbook using include_role" 10 | ] 11 | }, 12 | { 13 | "cell_type": "code", 14 | "execution_count": 1, 15 | "metadata": {}, 16 | "outputs": [], 17 | "source": [ 18 | "#ansible.cfg\n", 19 | "[defaults]\n", 20 | "roles_path=roles" 21 | ] 22 | }, 23 | { 24 | "cell_type": "code", 25 | "execution_count": 2, 26 | "metadata": {}, 27 | "outputs": [ 28 | { 29 | "name": "stdout", 30 | "output_type": "stream", 31 | "text": [ 32 | "- downloading role 'hello_role2', owned by benthomasson\n", 33 | "- downloading role from https://github.com/benthomasson/hello-role2/archive/master.tar.gz\n", 34 | "- extracting benthomasson.hello_role2 to /private/var/folders/p8/mttm7w913kq_v0wyfl9khlpc0000gn/T/ansible_kernel_playbookNcMnGI/roles/benthomasson.hello_role2\n", 35 | "- benthomasson.hello_role2 (master) was installed successfully\n", 36 | "\n", 37 | "TASK [benthomasson.hello_role2 : debug] ****************************************\n", 38 | "ok: [localhost] => {\n", 39 | " \"msg\": \"Hello world!\"\n", 40 | "}\n", 41 | "TASK [benthomasson.hello_role2 : debug] ****************************************\n", 42 | "ok: [localhost] => {\n", 43 | " \"msg\": \"Hello world!\"\n", 44 | "}\n" 45 | ] 46 | } 47 | ], 48 | "source": [ 49 | "#play\n", 50 | "hosts: localhost\n", 51 | "gather_facts: false\n", 52 | "roles:\n", 53 | " - benthomasson.hello_role2" 54 | ] 55 | }, 56 | { 57 | "cell_type": "code", 58 | "execution_count": null, 59 | "metadata": {}, 60 | "outputs": [], 61 | "source": [] 62 | }, 63 | { 64 | "cell_type": "code", 65 | "execution_count": null, 66 | "metadata": {}, 67 | "outputs": [], 68 | "source": [] 69 | } 70 | ], 71 | "metadata": { 72 | "kernelspec": { 73 | "display_name": "Ansible", 74 | "language": "ansible", 75 | "name": "ansible" 76 | }, 77 | "language_info": { 78 | "codemirror_mode": "yaml", 79 | "file_extension": ".yml", 80 | "mimetype": "text/yaml", 81 | "name": "ansible" 82 | } 83 | }, 84 | "nbformat": 4, 85 | "nbformat_minor": 2 86 | } 87 | -------------------------------------------------------------------------------- /tests/HelloWorld.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Tests that a simple task runs\n", 8 | "\n", 9 | "* Passes if the debug command runs - PASS" 10 | ] 11 | }, 12 | { 13 | "cell_type": "code", 14 | "execution_count": 1, 15 | "metadata": {}, 16 | "outputs": [ 17 | { 18 | "name": "stdout", 19 | "output_type": "stream", 20 | "text": [ 21 | "TASK [debug] *******************************************************************\n", 22 | "ok: [localhost] => {\n", 23 | " \"msg\": \"Hello world!\"\n", 24 | "}\n" 25 | ] 26 | } 27 | ], 28 | "source": [ 29 | "debug:" 30 | ] 31 | }, 32 | { 33 | "cell_type": "code", 34 | "execution_count": null, 35 | "metadata": {}, 36 | "outputs": [], 37 | "source": [] 38 | } 39 | ], 40 | "metadata": { 41 | "kernelspec": { 42 | "display_name": "Ansible", 43 | "language": "ansible", 44 | "name": "ansible" 45 | }, 46 | "language_info": { 47 | "codemirror_mode": "yaml", 48 | "file_extension": ".yml", 49 | "mimetype": "text/yaml", 50 | "name": "ansible" 51 | } 52 | }, 53 | "nbformat": 4, 54 | "nbformat_minor": 2 55 | } 56 | -------------------------------------------------------------------------------- /tests/MissingArgumentColon.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Tests that module arguments with a missing colon returns error\n", 8 | "\n", 9 | "* Passes if the error message is shown - PASS" 10 | ] 11 | }, 12 | { 13 | "cell_type": "code", 14 | "execution_count": 1, 15 | "metadata": {}, 16 | "outputs": [ 17 | { 18 | "name": "stdout", 19 | "output_type": "stream", 20 | "text": [ 21 | "fatal: [localhost]: FAILED! => this task 'debug' has extra params, which is only allowed in the following modules: shell, win_shell, include_vars, add_host, raw, include_role, meta, set_fact, include, import_tasks, script, import_role, include_tasks, group_by, command, win_command\n", 22 | "\n", 23 | "The error appears to have been in '/private/var/folders/p8/mttm7w913kq_v0wyfl9khlpc0000gn/T/ansible_kernel_playbookh_NA6j/next_task0.yml': line 1, column 3, but may\n", 24 | "be elsewhere in the file depending on the exact syntax problem.\n", 25 | "\n", 26 | "The offending line appears to be:\n", 27 | "\n", 28 | "\n", 29 | "- debug: msg\n", 30 | " ^ here\n", 31 | "\n", 32 | "\n", 33 | "Playbook ended\n", 34 | "Context lost!\n" 35 | ] 36 | } 37 | ], 38 | "source": [ 39 | "debug:\n", 40 | " msg" 41 | ] 42 | }, 43 | { 44 | "cell_type": "code", 45 | "execution_count": null, 46 | "metadata": {}, 47 | "outputs": [], 48 | "source": [] 49 | }, 50 | { 51 | "cell_type": "code", 52 | "execution_count": null, 53 | "metadata": {}, 54 | "outputs": [], 55 | "source": [] 56 | } 57 | ], 58 | "metadata": { 59 | "kernelspec": { 60 | "display_name": "Ansible", 61 | "language": "ansible", 62 | "name": "ansible" 63 | }, 64 | "language_info": { 65 | "codemirror_mode": "yaml", 66 | "file_extension": ".yml", 67 | "mimetype": "text/yaml", 68 | "name": "ansible" 69 | } 70 | }, 71 | "nbformat": 4, 72 | "nbformat_minor": 2 73 | } 74 | -------------------------------------------------------------------------------- /tests/MissingColon.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Tests that a missing colon on the module name pops up docs\n", 8 | "\n", 9 | "* Passes if the documentation pager shows the ansible-doc for the module - PASS" 10 | ] 11 | }, 12 | { 13 | "cell_type": "code", 14 | "execution_count": 2, 15 | "metadata": {}, 16 | "outputs": [], 17 | "source": [ 18 | "debug" 19 | ] 20 | } 21 | ], 22 | "metadata": { 23 | "kernelspec": { 24 | "display_name": "Ansible", 25 | "language": "ansible", 26 | "name": "ansible" 27 | }, 28 | "language_info": { 29 | "codemirror_mode": "yaml", 30 | "file_extension": ".yml", 31 | "mimetype": "text/yaml", 32 | "name": "ansible" 33 | } 34 | }, 35 | "nbformat": 4, 36 | "nbformat_minor": 2 37 | } 38 | -------------------------------------------------------------------------------- /tests/NoHostsPlay.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Tests that plays without hosts raise an error\n", 8 | "\n", 9 | "* Passes if an error message is shown - PASS" 10 | ] 11 | }, 12 | { 13 | "cell_type": "code", 14 | "execution_count": 2, 15 | "metadata": {}, 16 | "outputs": [ 17 | { 18 | "name": "stdout", 19 | "output_type": "stream", 20 | "text": [ 21 | "\n", 22 | "ERROR! the field 'hosts' is required but was not set\n" 23 | ] 24 | } 25 | ], 26 | "source": [ 27 | "#play\n", 28 | "gather_facts: false" 29 | ] 30 | }, 31 | { 32 | "cell_type": "code", 33 | "execution_count": null, 34 | "metadata": {}, 35 | "outputs": [], 36 | "source": [] 37 | } 38 | ], 39 | "metadata": { 40 | "kernelspec": { 41 | "display_name": "Ansible", 42 | "language": "ansible", 43 | "name": "ansible" 44 | }, 45 | "language_info": { 46 | "codemirror_mode": "yaml", 47 | "file_extension": ".yml", 48 | "mimetype": "text/yaml", 49 | "name": "ansible" 50 | } 51 | }, 52 | "nbformat": 4, 53 | "nbformat_minor": 2 54 | } 55 | -------------------------------------------------------------------------------- /tests/NoNamePlay.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Tests that a play does not need a name\n", 8 | "\n", 9 | "* Passes if debug and ping commands run - PASS" 10 | ] 11 | }, 12 | { 13 | "cell_type": "code", 14 | "execution_count": 1, 15 | "metadata": {}, 16 | "outputs": [], 17 | "source": [ 18 | "#play\n", 19 | "hosts: localhost\n", 20 | "gather_facts: false" 21 | ] 22 | }, 23 | { 24 | "cell_type": "code", 25 | "execution_count": 2, 26 | "metadata": {}, 27 | "outputs": [ 28 | { 29 | "name": "stdout", 30 | "output_type": "stream", 31 | "text": [ 32 | "TASK [debug] *******************************************************************\n", 33 | "ok: [localhost] => {\n", 34 | " \"msg\": \"Hello world!\"\n", 35 | "}\n" 36 | ] 37 | } 38 | ], 39 | "source": [ 40 | "debug:" 41 | ] 42 | }, 43 | { 44 | "cell_type": "code", 45 | "execution_count": 3, 46 | "metadata": {}, 47 | "outputs": [ 48 | { 49 | "name": "stdout", 50 | "output_type": "stream", 51 | "text": [ 52 | "TASK [ping] ********************************************************************\n", 53 | "ok: [localhost] => {\n", 54 | " \"changed\": false, \n", 55 | " \"invocation\": {\n", 56 | " \"module_args\": {\n", 57 | " \"data\": \"pong\"\n", 58 | " }\n", 59 | " }, \n", 60 | " \"ping\": \"pong\"\n", 61 | "}\n" 62 | ] 63 | } 64 | ], 65 | "source": [ 66 | "ping:" 67 | ] 68 | }, 69 | { 70 | "cell_type": "code", 71 | "execution_count": null, 72 | "metadata": {}, 73 | "outputs": [], 74 | "source": [] 75 | }, 76 | { 77 | "cell_type": "code", 78 | "execution_count": null, 79 | "metadata": {}, 80 | "outputs": [], 81 | "source": [] 82 | } 83 | ], 84 | "metadata": { 85 | "kernelspec": { 86 | "display_name": "Ansible", 87 | "language": "ansible", 88 | "name": "ansible" 89 | }, 90 | "language_info": { 91 | "codemirror_mode": "yaml", 92 | "file_extension": ".yml", 93 | "mimetype": "text/yaml", 94 | "name": "ansible" 95 | } 96 | }, 97 | "nbformat": 4, 98 | "nbformat_minor": 2 99 | } 100 | -------------------------------------------------------------------------------- /tests/UnknownModule.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Tests that unknown module names raise an error\n", 8 | "\n", 9 | "* Passes if an error is displayed - PASS" 10 | ] 11 | }, 12 | { 13 | "cell_type": "code", 14 | "execution_count": 1, 15 | "metadata": {}, 16 | "outputs": [], 17 | "source": [ 18 | "dfdffdf" 19 | ] 20 | }, 21 | { 22 | "cell_type": "code", 23 | "execution_count": null, 24 | "metadata": {}, 25 | "outputs": [], 26 | "source": [] 27 | } 28 | ], 29 | "metadata": { 30 | "kernelspec": { 31 | "display_name": "Ansible", 32 | "language": "ansible", 33 | "name": "ansible" 34 | }, 35 | "language_info": { 36 | "codemirror_mode": "yaml", 37 | "file_extension": ".yml", 38 | "mimetype": "text/yaml", 39 | "name": "ansible" 40 | } 41 | }, 42 | "nbformat": 4, 43 | "nbformat_minor": 2 44 | } 45 | -------------------------------------------------------------------------------- /tests/Unreachable.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Tests that a play continues with some unreachable hosts\n", 8 | "\n", 9 | "* Passes if ping and debug commands run - PASS" 10 | ] 11 | }, 12 | { 13 | "cell_type": "code", 14 | "execution_count": 12, 15 | "metadata": {}, 16 | "outputs": [], 17 | "source": [ 18 | "#inventory\n", 19 | "unreachable_host\n", 20 | "localhost " 21 | ] 22 | }, 23 | { 24 | "cell_type": "code", 25 | "execution_count": 13, 26 | "metadata": {}, 27 | "outputs": [ 28 | { 29 | "name": "stdout", 30 | "output_type": "stream", 31 | "text": [] 32 | } 33 | ], 34 | "source": [ 35 | "#play\n", 36 | "name: unreachable test\n", 37 | "hosts: all\n", 38 | "gather_facts: false" 39 | ] 40 | }, 41 | { 42 | "cell_type": "code", 43 | "execution_count": 14, 44 | "metadata": {}, 45 | "outputs": [ 46 | { 47 | "name": "stdout", 48 | "output_type": "stream", 49 | "text": [ 50 | "TASK [ping] ********************************************************************\n", 51 | "fatal: [unreachable_host]: UNREACHABLE!\n", 52 | "ok: [localhost] => {\n", 53 | " \"changed\": false, \n", 54 | " \"invocation\": {\n", 55 | " \"module_args\": {\n", 56 | " \"data\": \"pong\"\n", 57 | " }\n", 58 | " }, \n", 59 | " \"ping\": \"pong\"\n", 60 | "}\n" 61 | ] 62 | } 63 | ], 64 | "source": [ 65 | "ping:" 66 | ] 67 | }, 68 | { 69 | "cell_type": "code", 70 | "execution_count": 15, 71 | "metadata": {}, 72 | "outputs": [ 73 | { 74 | "name": "stdout", 75 | "output_type": "stream", 76 | "text": [ 77 | "TASK [debug] *******************************************************************\n", 78 | "ok: [localhost] => {\n", 79 | " \"msg\": \"Hello world!\"\n", 80 | "}\n" 81 | ] 82 | } 83 | ], 84 | "source": [ 85 | "debug:" 86 | ] 87 | }, 88 | { 89 | "cell_type": "code", 90 | "execution_count": null, 91 | "metadata": {}, 92 | "outputs": [], 93 | "source": [] 94 | } 95 | ], 96 | "metadata": { 97 | "kernelspec": { 98 | "display_name": "Ansible", 99 | "language": "ansible", 100 | "name": "ansible" 101 | }, 102 | "language_info": { 103 | "codemirror_mode": "yaml", 104 | "file_extension": ".yml", 105 | "mimetype": "text/yaml", 106 | "name": "ansible" 107 | } 108 | }, 109 | "nbformat": 4, 110 | "nbformat_minor": 2 111 | } 112 | --------------------------------------------------------------------------------