├── .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 | [](https://travis-ci.com/ansible/ansible-jupyter-kernel)
4 | [](https://mybinder.org/v2/gh/ansible/ansible-jupyter-kernel/master)
5 |
6 |
7 |
8 | 
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 | [](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] [