{"id":15292067,"url":"https://github.com/uberspace/paternoster","last_synced_at":"2025-03-17T16:11:01.396Z","repository":{"id":52716309,"uuid":"68200087","full_name":"Uberspace/paternoster","owner":"Uberspace","description":"Paternoster allows you to run Ansible playbooks like ordinary Python or Bash scripts.","archived":false,"fork":false,"pushed_at":"2021-04-20T10:23:42.000Z","size":235,"stargazers_count":123,"open_issues_count":12,"forks_count":4,"subscribers_count":13,"default_branch":"master","last_synced_at":"2025-02-17T09:33:07.892Z","etag":null,"topics":["ansible","privileges","python","scripting","sudo"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Uberspace.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2016-09-14T11:23:16.000Z","updated_at":"2025-02-10T15:44:54.000Z","dependencies_parsed_at":"2022-08-22T08:21:00.071Z","dependency_job_id":null,"html_url":"https://github.com/Uberspace/paternoster","commit_stats":null,"previous_names":[],"tags_count":36,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Uberspace%2Fpaternoster","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Uberspace%2Fpaternoster/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Uberspace%2Fpaternoster/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Uberspace%2Fpaternoster/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Uberspace","download_url":"https://codeload.github.com/Uberspace/paternoster/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":244066180,"owners_count":20392406,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ansible","privileges","python","scripting","sudo"],"created_at":"2024-09-30T16:16:22.608Z","updated_at":"2025-03-17T16:11:01.372Z","avatar_url":"https://github.com/Uberspace.png","language":"Python","readme":"# Paternoster [![Build Status](https://travis-ci.org/Uberspace/paternoster.svg?branch=master)](https://travis-ci.org/Uberspace/paternoster)\n\n\u003cimg align=\"left\" height=\"150\" src=\"logo.png\"\u003e\n\nPaternoster enables ansible playbooks to be run like normal bash or python\nscripts. It parses the given parameters using python's [argparse][] and the\npasses them on to the actual playbook via the ansible API. In addition it\nprovides an automated way to run commands as another user, which can be used to\ngive normal shell users special privileges, while still having a sleek and easy\nto understand user interface.\n\nAnsible 2.1.x to 2.10.x as well as python 2.7 to 3.8 is supported and tested\nautomatically. We recommend using ansible 2.8+ and python 3.6+.\n\nOnce everything is set up, a paternoster script can be used like this:\n\n```\n$ create-user --help\nusage: create-user [-h] -u USERNAME [-v]\n\nCreate a user.\n\nrequired arguments:\n  -u USERNAME, --username USERNAME\n                        name of the user to create\n\noptional arguments:\n  -h, --help            show this help message and exit\n  -v, --verbose         run with a lot of debugging output\n$ create-user -u luto\ncreating user luto\n```\n\nThe script looks like a normal ansible playbook, except for a few additions.\nFirstly, it uses a different shebang-line, which kicks off paternoster instead\nof ansible. Secondly, there is a special play at the beginning of the playbook,\nwhich contains the configuration for parameter parsing and other features.\n\n```yaml\n#!/usr/bin/env paternoster\n\n- hosts: paternoster\n  vars:\n    description: Create a user.\n    parameters:\n      - name: username\n        short: u\n        help: \"name of the user to create\"\n        type: paternoster.types.restricted_str\n        required: yes\n        type_params:\n          regex: \"^[a-z]+$\"\n\n- hosts: localhost\n  tasks:\n    - debug: msg=\"creating user {{ param_username }}\"\n```\n\nFor more information on how to develop scripts using paternoster, please refer\nthe the corresponding sub-document:\n[`doc/script_development.md`][docs-script_dev].\n\n## Privilege Escalation\n\nPaternoster also provides an automated way to run commands as another user. To\nuse this feature, set the `become_user` to the desired username. This causes\npaternoster to execute itself as the given user using _sudo_. For this to work a\nsudoers-config has to be created by the developer.\n\nPlease refer to the Deployment section of this document for further details.\n\n# Deployment\n\n## Python-Module\n\nThe python module can be installed using pip: `pip install paternoster`.\n\nNote that this is the only distribution packaged by us. We do not and cannot\ncheck the content of all other, following methods.\n\n## Fedora\n\nPaternoster is also available [as a Fedora package](https://src.fedoraproject.org/rpms/paternoster).\n\n```\ndnf install paternoster\n```\n\n## RHEL/CentOS\n\nPaternoster is also available in [EPEL](https://fedoraproject.org/wiki/EPEL) for RHEL7, RHEL8, CentOS7 and CentOS8.\n\n```\nyum install epel-release\nyum install paternoster\n```\n\n## AUR\n\nPaternoster is also available [as an AUR package](https://aur.archlinux.org/packages/paternoster/)\nfor arch linux.\n\n## sudo\n\nIf you are planning to let users execute certain commands as root,\na few changes to your `sudo`-configuration are needed. boils down to:\n\n```\nALL ALL = NOPASSWD: /usr/local/bin/your-script-name\n```\n\nThis line allows _any_ user to execute the given command as root.\n\nPlease refer to the [`sudoers(5)`-manpage][man-sudoers] for details.\n\n## Notes\n\n- This library makes use of the [tldextract-module][]. Internally this\n  relies on a list of top level domains, which changes every so often.\n  Execute the `tldextract --update`-command as root in a _cronjob_ or\n  similar to keep the list up to date.\n\n# Library-Development\n\nMost tasks can be achieved by writing scripts only. Therefore, the library does\nnot need to be changed in most cases. Sometimes it might be desirable to provide\na new type or feature to all other scripts. To fulfill these needs, the\nfollowing section outlines the setup and development process for library.\n\n## Setup\n\nTo get a basic environment up and running, use the following commands:\n\n```shell\nvirtualenv venv --python python2.7\nsource venv/bin/activate\npython setup.py develop\npip install -r requirements.txt\npre-commit install --overwrite --install-hooks\n```\n\nThis project uses _Python_ `2.7`, because _Python_ `3.x` is not yet supported by\nansible. All non-ansible code is tested with python 3 as well.\n\n### Vagrant\n\nMost features, where unit tests suffice can be tested using a _virtualenv_ only.\nIf your development relies on the sudo-mechanism, you can spin up a [vagrant\nVM][] which provides a dummy `uberspace-add-domain`-script as well as the\nlibrary-code in the `/vagrant`-directory.\n\n```shell\nvagrant up\nvagrant ssh\n```\n\nAnd inside the host:\n\n```\nLast login: Wed Aug  3 17:23:02 2016 from 10.0.2.2\n[vagrant@localhost ~]$ uberspace-add-domain -d a.com -v\n\nPLAY [test play] ************** (...)\n```\n\nIf you want to add your own scripts, just add the corresponding files in\n`vagrant/files/scripts`. You can deploy it using the following command:\n`ansible-playbook vagrant/site.yml --tags scripts`. Once your script has been\ndeployed, you can just edit the source file to make further changes, as the file\nis symlinked, not copied.\n\n## Tests\n\n### Linter\n\nTo lint the source code, you can run:\n\n```shell\ntox -e lint\n```\n\n### Unit Tests\n\nThe core functionality of this library can be tested using the `tox`- command.\nIf only _Python_ `2.x` or `3.x` should be tested, the `-e` parameter can be\nused, like so: `tox -e py36-ansible23`, `tox -e py27-ansible22`. New tests\nshould be added to the `paternoster/test`-directory. Please refer to the\n[pytest-documentation][] for further details.\n\nNOTE: you might need to install the the proper _\"devel\"_ package, for the Python\nversions you want to test.\n\n### Integration Tests\n\nSome features (like the `become_user` function) require a correctly setup Linux\nenvironment. They can be tested using the provided ansible playbooks in\n`vagrant/tests`.\n\nThe playbooks can be invoked using the `run_integration_tests.py`-utility:\n\n```\n$ ./vagrant/run_integration_tests.py --file test_variables.yml\n=== running test_variables.yml with ansible\u003e=2.1,\u003c2.2\n=== running test_variables.yml with ansible\u003e=2.2,\u003c2.3\n=== running test_variables.yml with ansible\u003e=2.3,\u003c2.4\n$ ./vagrant/run_integration_tests.py ansible22 --file test_variables.yml\n=== running test_variables.yml with ansible\u003e=2.2,\u003c2.3\n$ ./vagrant/run_integration_tests.py --help\nusage: run_integration_tests.py [-h] [--file FILE]\n                                [{ansible21,ansible22,ansible23,all}]\n\nRun paternoster integration tests.\n\n(...)\n```\n\n#### Boilerplate\n\nA typical [ansible playbook][] for a system-test might look like this:\n\n```yaml\n- name: give this test a proper name\n  hosts: all\n  tasks:\n    - include: drop_script.yml\n      vars:\n        ignore_script_errors: yes\n        script_params: --some-parameter\n        playbook: |\n          - hosts: all\n            tasks:\n              - debug: msg=\"hello world\"\n        script: |\n          #!/bin/env python2.7\n          # some python code to test\n\n    - assert:\n        that:\n          - \"script.stdout_lines[0] == 'something'\"\n```\n\nMost of the heavy lifting is done by the included `drop_script.yml`-file. It\ncreates the required python-script \u0026 playbook, executes it and stores the result\nin the `script`-variable. After the execution, all created files are removed.\nAfter the script has been executed, the [`assert`-module][ansible-assert-module]\ncan be used to check the results.\n\nThere are several parameters to control the behavior of `drop_script.yml`:\n\n| Name                   | Optional               | Description                                                                                   |\n| ---------------------- | ---------------------- | --------------------------------------------------------------------------------------------- |\n| `script`               | no                     | the **content** of a python script to save as `/usr/local/bin/uberspace-unittest` and execute |\n| `playbook`             | yes (default: empty)   | the **content** of a playbook to save as `/opt/uberspace/playbooks/uberspace-unittest.yml`    |\n| `ignore_script_errors` | yes (default: `false`) | whether to continue even if python script has a non-zero exitcode                             |\n| `script_params`        | yes (default: empty)   | command line parameters for the script (e.g. `\"--domain foo.com\"`)                            |\n\n## Releasing a new version\n\nAssuming you have been handed the required credentials, a new version can be\nreleased as follows.\n\n1. adapt the version in `setup.py`, according to [semver](http://semver.org/)\n2. commit this change as `Version 1.2.3`\n3. tag the resulting commit as `v1.2.3`\n4. push the new tag as well as the `master` branch\n5. update the package on PyPI:\n\n```shell\nrm dist/*\npython setup.py sdist bdist_wheel\ntwine upload dist/*\n```\n\n# License\n\nAll code in this repository (including this document) is licensed under the MIT\nlicense. The logo (both the _png_ and _svg_ versions) is licensed unter the\n[CC-BY-NC-ND 4.0][] license.\n\n[ansible playbook]: http://docs.ansible.com/ansible/playbooks.html\n[ansible-assert-module]: http://docs.ansible.com/ansible/assert_module.html\n[argparse]: https://docs.python.org/2/library/argparse.html\n[cc-by-nc-nd 4.0]: https://creativecommons.org/licenses/by-nc-nd/4.0/\n[docs-script_dev]: doc/script_development.md\n[man-sudoers]: https://www.sudo.ws/man/1.8.17/sudoers.man.html\n[pytest-documentation]: http://doc.pytest.org/\n[semver]: http://semver.org/\n[tldextract-module]: https://github.com/john-kurkowski/tldextract\n[vagrant-vm]: https://vagrantup.com/\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fuberspace%2Fpaternoster","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fuberspace%2Fpaternoster","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fuberspace%2Fpaternoster/lists"}