{ "info": { "author": "Carl Montanari", "author_email": "carl.r.montanari@gmail.com", "bugtrack_url": null, "classifiers": [ "License :: OSI Approved :: MIT License", "Operating System :: MacOS", "Operating System :: POSIX :: Linux", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7", "Programming Language :: Python :: 3.8" ], "description": "![](https://github.com/carlmontanari/nornsible/workflows/build/badge.svg)\n[![PyPI version](https://badge.fury.io/py/nornsible.svg)](https://badge.fury.io/py/nornsible)\n[![Python 3.6](https://img.shields.io/badge/python-3.6-blue.svg)](https://www.python.org/downloads/release/python-360/)\n[![Python 3.7](https://img.shields.io/badge/python-3.7-blue.svg)](https://www.python.org/downloads/release/python-370/)\n[![Python 3.8](https://img.shields.io/badge/python-3.8-blue.svg)](https://www.python.org/downloads/release/python-380/)\n[![Code Style](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/ambv/black)\n\nNornsible\n=======\n\nBring some of the nice things about Ansible to Nornir!\n\nThe idea behind Nornsible is to allow for Nornir scripts to be written to operate on an entire environment, and then limited to a subset of host(s) based on simple command line arguments. Of course you can simply do this yourself, but why not let nornsible handle it for you!\n\nNornsible provides the ability to -- via command line arguments -- filter Nornir inventories by hostname or group name, or both. There is also a handy flag to set the number of workers; quite useful for setting workers equal to 1 for troubleshooting purposes.\n\nNornsible all supports the concept of tags. Tags correspond to the name of *custom* tasks and operate very much like tags in Ansible. Provide a list of tags to execute, and Nornsible will ensure that Nornir only runs those tasks. Provide a list of tags to skip, and Nornsible will ensure that Nornir only runs those not in that list. Easy peasy.\n\nFinally, Nornsible supports multiple inventory files as well as dynamic inventory files -- just like Ansible.\n\n\n# How does Nornsible work?\n\nNornsible accepts an instantiated Nornir object as an argument and returns a slightly modified Nornir object. Nornsible sets the desired number of workers if applicable, and adds an attribute for \"run_tags\" and \"skip_tags\" based on your command line input.\n\nTo take advantage of the tags feature Nornsible provides a decorator that you can use to wrap your custom tasks. This decorator inspects the task being ran and checks the task name against the lists of run and skip tags. If the task is allowed, Nornsible simply allows the task to run as per normal, if it is *not* allowed, Nornsible will print a pretty message and move on.\n\nNornsible inventory can be used by simply installing Nornsible and setting the inventory plugin in your config file as follows:\n\n```yaml\ninventory:\n plugin: nornsible.inventory.AnsibleInventory\n options:\n inventory: inventory.yaml\n```\n\nNote that instead of `hostsfile` Nornsible inventory uses `inventory` -- this is intentional to make sure to differentiate between the standard Nornir Ansible support and nornsible.\n\n# Caveats\n\nNornsible breaks some things! Most notably it breaks \"normal\" Nornir filtering *after* the Nornir object is \"nornsible-ified\". This can probably be fixed but at the moment it doesn't seem like that big a deal, so I'm not bothering!\n\nIf you want to do \"normal\" Nornir filtering -- do this *before* passing the nornir object to Nornsible.\n\nNornsible, at the moment, can only wrap custom tasks. This can probably be improved upon as well, but at the moment the decorator wrapping custom tasks solution seems to work pretty well.\n\n\n# Installation\n\nInstallation via pip:\n\n```\npip install nornsible\n```\n\nTo install from this repository:\n\n```\npip install git+https://github.com/carlmontanari/nornsible\n```\n\nTo install from source:\n\n```\ngit clone https://github.com/carlmontanari/nornsible\ncd nornsible\npython setup.py install\n```\n\n\n# Usage\n\nImport stuff:\n\n```\nfrom nornsible import InitNornsible, nornsible_task\n```\n\nDecorate custom tasks with `nornsible_task` if desired:\n\n```\n@nornsible_task\ndef my_custom_task(task):\n```\n\nCreate your Nornir object and then pass it through InitNornsible:\n\n```\nnr = InitNornir(config_file=\"config.yaml\")\nnr = InitNornsible(nr)\n```\n\nRun a custom task wrapped by `nornsible_task`:\n\n```\nnr.run(task=my_custom_task)\n```\n\nRun your script with any of the following command line switches:\n\n| Purpose | Short Flag | Long Flag | Allowed Options\n| -----------------|---------------|------------|-------------------|\n| set num_workers | -w | --workers | integer |\n| limit host(s) | -l | --limit | comma sep string |\n| limit group(s) | -g | --groups | comma sep string |\n| run tag(s) | -t | --tags | comma sep string |\n| skip tag(s) | -s | --skip | comma sep string |\n\nTo set number of workers to 1 for troubleshooting purposes:\n\n```\npython my_nornir_script.py -w 1\n```\n\nTo limit to the \"sea\" group (from your Nornir inventory):\n\n```\npython my_nornir_script.py -g sea\n```\n\nTo run only the tasks named \"create_configs\" and \"deploy_configs\" (assuming you've wrapped all of your tasks with `nornsible_task`!):\n\n```\npython my_nornir_script.py -t create_configs,deploy_configs\n```\n\nTo run only the tasks named \"create_configs\" and \"deploy_configs\" against the \"sea-eos-1\" host:\n\n```\npython my_nornir_script.py -t create_configs,deploy_configs -l sea-eos-1\n```\n\n\n# FAQ\n\nTBA, probably things though!\n\n# Linting and Testing\n\n## Linting\n\nThis project uses [black](https://github.com/psf/black) for auto-formatting. In addition to black, tox will execute [pylama](https://github.com/klen/pylama), and [pydocstyle](https://github.com/PyCQA/pydocstyle) for linting purposes. I've also added docstring linting with [darglint](https://github.com/terrencepreilly/darglint) which has been quite handy! Finally, I've been playing with type hints and have added mypy to the test/lint suite as well.\n\n## Testing\n\nI broke testing into two main categories -- unit and integration. Unit is what you would expect -- unit testing the code. Integration testing is for things that test more than one \"unit\" (generally function) at a time.\n\n\n# To Do\n\n- Add handling for \"not\" in host/group limit; i.e.: \"-t !localhost\" to run against all hosts *not* localhost.\n- Add more examples for using nornsible inventory in different ways -- i.e. multiple inventory, dynamic inventory, hash_behavior settings, etc.\n- Add more detailed readme info on inventory stuff.\n- Add support for host/group vars in directories in the host/group vars parent directory...\n - i.e. `host_vars/myhost/somevar1.yaml` and `host_vars/myhost/somevar2.yaml`\n- Add integration testing for inventory bits.\n- Fix/add logging -- ensure inventory logs to nornir log as per usual, but also create a nornsible log for all nornsible \"stuff\".\n\n", "description_content_type": "text/markdown", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "", "keywords": "", "license": "", "maintainer": "", "maintainer_email": "", "name": "nornsible", "package_url": "https://pypi.org/project/nornsible/", "platform": "", "project_url": "https://pypi.org/project/nornsible/", "project_urls": null, "release_url": "https://pypi.org/project/nornsible/2020.1.11/", "requires_dist": [ "colorama (>=0.3.9)", "nornir (>=2.2.0)" ], "requires_python": ">=3.6", "summary": "Ansible-like inventory utility for Nornir.", "version": "2020.1.11", "yanked": false, "yanked_reason": null }, "last_serial": 6438004, "releases": { "2019.10.28": [ { "comment_text": "", "digests": { "md5": "5a794cc7dc306f252c0a778fa9221814", "sha256": "b37ae758f662774db6edc45992496c2bb149e3d50fcaa3238ea2632278ca304f" }, "downloads": -1, "filename": "nornsible-2019.10.28-py3-none-any.whl", "has_sig": false, "md5_digest": "5a794cc7dc306f252c0a778fa9221814", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.6", "size": 7211, "upload_time": "2019-10-28T15:21:41", "upload_time_iso_8601": "2019-10-28T15:21:41.646966Z", "url": "https://files.pythonhosted.org/packages/76/f3/6d6ea74a5441c64dfe1e5023e2185594dcd3e5dc64d2c14888774b18fd06/nornsible-2019.10.28-py3-none-any.whl", "yanked": false, "yanked_reason": null }, { "comment_text": "", "digests": { "md5": "73f9eaea70470add94c4d2b26eda1652", "sha256": "5ce8d303de1576bc6055c61804a07bdeba9373cab6ab4612037b04392a14af69" }, "downloads": -1, "filename": "nornsible-2019.10.28.tar.gz", "has_sig": false, "md5_digest": "73f9eaea70470add94c4d2b26eda1652", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.6", "size": 6490, "upload_time": "2019-10-28T15:21:42", "upload_time_iso_8601": "2019-10-28T15:21:42.673572Z", "url": "https://files.pythonhosted.org/packages/7f/18/d645cc7c49ea0cbb8138e164e98d1138056269b03efa12447d265b8013ba/nornsible-2019.10.28.tar.gz", "yanked": false, "yanked_reason": null } ], "2019.11.5": [ { "comment_text": "", "digests": { "md5": "df6991ec5db26a0585650ce702889189", "sha256": "ed767b8ee36d96e818a5230da5494aae713691c9cdae2b8b506824b147c62d73" }, "downloads": -1, "filename": "nornsible-2019.11.5-py3-none-any.whl", "has_sig": false, "md5_digest": "df6991ec5db26a0585650ce702889189", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.6", "size": 7214, "upload_time": "2019-11-06T01:46:25", "upload_time_iso_8601": "2019-11-06T01:46:25.477131Z", "url": "https://files.pythonhosted.org/packages/d1/bc/5bc7b75f1a532dbae938854bfa568eea36ab2b70fd303b0d4266bd13003d/nornsible-2019.11.5-py3-none-any.whl", "yanked": false, "yanked_reason": null }, { "comment_text": "", "digests": { "md5": "d42560f9f6068f6bd562bcb3b756f7d6", "sha256": "c2d778d587458faaa6fbd6f6f0e0db66b6f9626d359a73df3ed4f129124eac78" }, "downloads": -1, "filename": "nornsible-2019.11.5.tar.gz", "has_sig": false, "md5_digest": "d42560f9f6068f6bd562bcb3b756f7d6", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.6", "size": 7313, "upload_time": "2019-11-06T01:46:27", "upload_time_iso_8601": "2019-11-06T01:46:27.071923Z", "url": "https://files.pythonhosted.org/packages/d6/3b/5c277c683183e0a662299e838d48b903817832823c81a0526f5f1889c36d/nornsible-2019.11.5.tar.gz", "yanked": false, "yanked_reason": null } ], "2019.9.16": [ { "comment_text": "", "digests": { "md5": "1a6687947df682c50cd9d8691b3f0c27", "sha256": "351b72bf39ed3e54f566344959ce5b6358c2d6487c3c9be3d373c5a25714e063" }, "downloads": -1, "filename": "nornsible-2019.9.16-py3-none-any.whl", "has_sig": false, "md5_digest": "1a6687947df682c50cd9d8691b3f0c27", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.6", "size": 4533, "upload_time": "2019-09-17T03:52:15", "upload_time_iso_8601": "2019-09-17T03:52:15.138786Z", "url": "https://files.pythonhosted.org/packages/c2/35/085ad33f0c574c73ca66508ea32743f45d353e57caac814a75ff671112f4/nornsible-2019.9.16-py3-none-any.whl", "yanked": false, "yanked_reason": null }, { "comment_text": "", "digests": { "md5": "0d5c664a7638a2d997ff67f4c1960c7a", "sha256": "67a098913ae17c0e2b652cbfe4a202a2ac4bfb84378776957f6bd32954efc357" }, "downloads": -1, "filename": "nornsible-2019.9.16.tar.gz", "has_sig": false, "md5_digest": "0d5c664a7638a2d997ff67f4c1960c7a", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.6", "size": 3428, "upload_time": "2019-09-17T03:52:17", "upload_time_iso_8601": "2019-09-17T03:52:17.532331Z", "url": "https://files.pythonhosted.org/packages/22/d2/07eb4b0db77539c756beb82866178232195a935e76de4fa947b8006bbd6e/nornsible-2019.9.16.tar.gz", "yanked": false, "yanked_reason": null } ], "2019.9.17": [ { "comment_text": "", "digests": { "md5": "0db909a3a49b26f8e03df5de4f106827", "sha256": "76a93c31c65ad55920f606fa4e73f990d835aa06ac2cad9f85f4c5e1b867bb56" }, "downloads": -1, "filename": "nornsible-2019.9.17-py3-none-any.whl", "has_sig": false, "md5_digest": "0db909a3a49b26f8e03df5de4f106827", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.6", "size": 6461, "upload_time": "2019-09-18T02:32:44", "upload_time_iso_8601": "2019-09-18T02:32:44.505876Z", "url": "https://files.pythonhosted.org/packages/32/29/a3d4ccb144242c9e2cc32ad14511c46514d023eef06ec215f2ea8fc07966/nornsible-2019.9.17-py3-none-any.whl", "yanked": false, "yanked_reason": null }, { "comment_text": "", "digests": { "md5": "401b74b6f49768154d894f16e59fa890", "sha256": "bc71f23d3569a38c45fdc580004111ad5292f0d94e198f61f210881cd2afe89a" }, "downloads": -1, "filename": "nornsible-2019.9.17.tar.gz", "has_sig": false, "md5_digest": "401b74b6f49768154d894f16e59fa890", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.6", "size": 5708, "upload_time": "2019-09-18T02:32:45", "upload_time_iso_8601": "2019-09-18T02:32:45.947245Z", "url": "https://files.pythonhosted.org/packages/07/5b/806e5109b0e39716d34159f5b33cc197f1137c63cb98f6ef7d715b4ba82d/nornsible-2019.9.17.tar.gz", "yanked": false, "yanked_reason": null } ], "2019.9.20": [ { "comment_text": "", "digests": { "md5": "1d9b6616a635cf27f62cb1c3ea995c30", "sha256": "b2906ad0218842cf1280f3177afb1f3b7efc51c46f7a48ad2d71f093151f3d7a" }, "downloads": -1, "filename": "nornsible-2019.9.20-py3-none-any.whl", "has_sig": false, "md5_digest": "1d9b6616a635cf27f62cb1c3ea995c30", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.6", "size": 7169, "upload_time": "2019-09-20T16:42:05", "upload_time_iso_8601": "2019-09-20T16:42:05.109764Z", "url": "https://files.pythonhosted.org/packages/6a/8c/dfe1333ff946a809f6c4395822587405c941d31abfb23a6e7381580b3c88/nornsible-2019.9.20-py3-none-any.whl", "yanked": false, "yanked_reason": null }, { "comment_text": "", "digests": { "md5": "3774d4635d4acd9047ca74b396b25562", "sha256": "b59de6409eabb42eac527d0fcb2cd27554d54910d44af99cd0434691bc6cae5d" }, "downloads": -1, "filename": "nornsible-2019.9.20.tar.gz", "has_sig": false, "md5_digest": "3774d4635d4acd9047ca74b396b25562", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.6", "size": 6455, "upload_time": "2019-09-20T16:42:06", "upload_time_iso_8601": "2019-09-20T16:42:06.193530Z", "url": "https://files.pythonhosted.org/packages/f8/d4/a8988d23358be2bd3ab1fca4df45282f45efc856839b242321ccb168d8a9/nornsible-2019.9.20.tar.gz", "yanked": false, "yanked_reason": null } ], "2020.1.11": [ { "comment_text": "", "digests": { "md5": "ed3cc04d147903fa6ce0d349cd33a0bb", "sha256": "4295599b13b4df11320cf658901aacfd6443f06a362a8606126a5ed61af6581d" }, "downloads": -1, "filename": "nornsible-2020.1.11-py3-none-any.whl", "has_sig": false, "md5_digest": "ed3cc04d147903fa6ce0d349cd33a0bb", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.6", "size": 11396, "upload_time": "2020-01-11T23:48:46", "upload_time_iso_8601": "2020-01-11T23:48:46.277207Z", "url": "https://files.pythonhosted.org/packages/09/77/a9ed08f2d3e43a30f9899a574cf184566dc02220959d55377e39bd0c60de/nornsible-2020.1.11-py3-none-any.whl", "yanked": false, "yanked_reason": null }, { "comment_text": "", "digests": { "md5": "ac6a684b8e2f119936025c20c8654462", "sha256": "5582cccce2b11f7b86e0f60142ad32db3804c90731061e34f8f1a93bc3d8e220" }, "downloads": -1, "filename": "nornsible-2020.1.11.tar.gz", "has_sig": false, "md5_digest": "ac6a684b8e2f119936025c20c8654462", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.6", "size": 12544, "upload_time": "2020-01-11T23:48:47", "upload_time_iso_8601": "2020-01-11T23:48:47.805729Z", "url": "https://files.pythonhosted.org/packages/da/64/d927c1a1acf4e9021f1e30c15bd00fe5b14c57c6896172d0c15f7fb772de/nornsible-2020.1.11.tar.gz", "yanked": false, "yanked_reason": null } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "ed3cc04d147903fa6ce0d349cd33a0bb", "sha256": "4295599b13b4df11320cf658901aacfd6443f06a362a8606126a5ed61af6581d" }, "downloads": -1, "filename": "nornsible-2020.1.11-py3-none-any.whl", "has_sig": false, "md5_digest": "ed3cc04d147903fa6ce0d349cd33a0bb", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.6", "size": 11396, "upload_time": "2020-01-11T23:48:46", "upload_time_iso_8601": "2020-01-11T23:48:46.277207Z", "url": "https://files.pythonhosted.org/packages/09/77/a9ed08f2d3e43a30f9899a574cf184566dc02220959d55377e39bd0c60de/nornsible-2020.1.11-py3-none-any.whl", "yanked": false, "yanked_reason": null }, { "comment_text": "", "digests": { "md5": "ac6a684b8e2f119936025c20c8654462", "sha256": "5582cccce2b11f7b86e0f60142ad32db3804c90731061e34f8f1a93bc3d8e220" }, "downloads": -1, "filename": "nornsible-2020.1.11.tar.gz", "has_sig": false, "md5_digest": "ac6a684b8e2f119936025c20c8654462", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.6", "size": 12544, "upload_time": "2020-01-11T23:48:47", "upload_time_iso_8601": "2020-01-11T23:48:47.805729Z", "url": "https://files.pythonhosted.org/packages/da/64/d927c1a1acf4e9021f1e30c15bd00fe5b14c57c6896172d0c15f7fb772de/nornsible-2020.1.11.tar.gz", "yanked": false, "yanked_reason": null } ], "vulnerabilities": [] }