{
"info": {
"author": "Engelbert Tejeda",
"author_email": "berttejeda@gmail.com",
"bugtrack_url": null,
"classifiers": [
"Development Status :: 3 - Alpha",
"Intended Audience :: Developers",
"Intended Audience :: Information Technology",
"License :: OSI Approved :: MIT License",
"Natural Language :: English",
"Programming Language :: Python :: 2",
"Programming Language :: Python :: 2.7",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.4",
"Programming Language :: Python :: 3.5",
"Programming Language :: Python :: 3.6",
"Programming Language :: Python :: 3.7"
],
"description": "\n\n**Table of Contents** *generated with [DocToc](https://github.com/thlorenz/doctoc)*\n\n- [Overview](#overview)\n- [TL;DR](#tldr)\n- [Use case and example](#use-case-and-example)\n - [Given](#given)\n - [Task](#task)\n - [Investigation](#investigation)\n - [Assessment](#assessment)\n - [Proposed Solution](#proposed-solution)\n- [Technical Details](#technical-details)\n - [Add hosts designation](#add-hosts-designation)\n - [Add vars key](#add-vars-key)\n - [Populate the vars block - defaults](#populate-the-vars-block---defaults)\n - [Populate the vars block - cli options](#populate-the-vars-block---cli-options)\n - [Populate the vars block - cli options - mapped variables](#populate-the-vars-block---cli-options---mapped-variables)\n - [Populate the vars block - help/message](#populate-the-vars-block---helpmessage)\n - [Populate the vars block - inventory](#populate-the-vars-block---inventory)\n - [Populate the vars block - embedded make-style functions](#populate-the-vars-block---embedded-make-style-functions)\n - [About make-style functions](#about-make-style-functions)\n - [Bash example:](#bash-example)\n - [Python example:](#python-example)\n - [Ruby example:](#ruby-example)\n - [Add tasks](#add-tasks)\n- [Usage Examples](#usage-examples)\n- [Installation](#installation)\n - [More Examples](#more-examples)\n- [Appendix](#appendix)\n - [Bastion Mode](#bastion-mode)\n - [Special Variables](#special-variables)\n - [ansible_playbook_command](#ansible_playbook_command)\n - [cli_provider](#cli_provider)\n - [__ansible_extra_options](#__ansible_extra_options)\n - [__tasks_file__](#__tasks_file__)\n - [__parameter_sets__](#__parameter_sets__)\n - [Parameter Sets](#parameter-sets)\n - [Mutually Exclusive Options](#mutually-exclusive-options)\n - [Simple Templating](#simple-templating)\n - [Single-Executable Releases](#single-executable-releases)\n - [Unit Testing](#unit-testing)\n- [TODO - Add more tests!](#todo---add-more-tests)\n- [License and Credits](#license-and-credits)\n\n\n\n\n\n# Overview\n\nThis is a task runner that serves as a higher-level automation layer to ansible\n\nThe script expects an ansible-playbook file as the task manifest.\n\nBy default, this is a file named 'Taskfile.yaml' in the current working directory.\n\nThe inspiration for the tool comes from the gnu make command, which operates in similar fashion, i.e.\n\n- A Makefile defines available build steps\n- The make command consumes the Makefile at runtime and exposes these steps as command-line options\n\nIf you are running this tool from Windows, please read the section on [Bastion Mode](#bastion_mode)\n\n# TL;DR\n\n- Ever wanted to add custom switches to the `ansible-playbook` command? Something like this:
\n`ansible-playbook -i myinventory.txt -d dbhost1 -w webhost1 -t value1 myplaybook.yaml`\n- Well, you can through the use of an ansible-playbook wrapper\n- That's where `tasks` comes in:
\n`tasks run -d dbhost1 -w webhost1 -t value1`
\ntranslates to:
\n`ansible-playbook -i /tmp/ansible-inventory16xdkrjd.tmp.ini -e dbhosts=\"dbhost1\" -e webhosts=\"webhost1\" -e some_value=\"value1\" -e echo=\"True\" Taskfile.yaml`\n\n1. Jump down to the [usage examples](#usage-examples) to see this in action\n2. Review the [installation](#installation) instructions if you want to test-drive it\n3. Read on if you want to dig deeper into the tool\n\n\n\n# Use case and example\n\n\n\n## Given\n\n1. An enterprise-grade application named contoso-app\n2. Multiple teams:\n- Development\n- Engineering\n- DBA\n- Operations\n- QA\n3. Ansible is the primary means of invoking business and operational processes across the numerous environment(s)\n\n\n\n## Task\n\nYou must ensure all teams adopt a standardized approach to running ansible workloads\n\n\n\n## Investigation\n\nUpon investigating the current approach, you observe the following: \n\n- Users tend to create wrapper scripts that call the ansible-playbook command\n- These scripts don't follow any naming convention, as you've noted:\n - run.sh\n - start.sh\n - playbook.sh\n- These shell scripts have common attributes:\n - Dynamically populate ansible-playbook variables via the --extra-vars option\n - Dynamically creating ansible inventories\n - Performing pre/post-flight tasks\n - Providing a command-line interface\n\n\n\n## Assessment\n\nAdvantages to the above approach:\n- Quick-n-dirty, anyone can get started relatively quickly with writing ansible automation\n\nDisadvantages:\n- Lack of standards: \n- Leads to difficulty in collaboration and code refactoring\n- Decreased re-usability of codebase\n - This design encourages standalone playbooks\n - Makes it more difficult to package actions as roles\n - Duplicate efforts across codebase\n\n\n\n## Proposed Solution\n\nEmploy a pre-execution script that operates above the `ansible-playbook` command:\n - Accomplishes the same as the above, but in more uniform manner\n - Support for custom command-line parameters/flags\n - Embedded dynamic inventory\n - Embedded make-style shell functions\n\nAdvantages to this approach:\n- Easier to manage\n - If you know YAML and Ansible, you can get started relatively quickly with writing ansible automation\n- Single executable (/usr/local/bin/tasks)\n\nDisadvantages:\n- Target ansible controller needs to have the `tasks` command installed\n\n[Back To Top](#top)\n\n\n# Technical Details\n\nAs stated in the [overview](#overview), this tool functions much like the *make* command in that it accepts an input file that essentially extends its cli options.\n\nWe create a specially formatted ansible-playbook that serves as a task definition file (by default, Taskfile.yaml).\n\nThis task definition file:\n\n- Acts like a command-line script\n- Is a valid ansible playbook (Taskfile.yaml), and can thus be launched with the `ansible-playbook` command\n- Variables available to the pre-execution phase are also available to the ansible execution phase\n\nIn the following sections, we'll be building a sample manifest/playbook named *Taskfile.yaml*\n\n[Back To Top](#top)\n\n\n## Add hosts designation\n\n\n Add hosts, gather_facts, etc
\n\n*Taskfile.yaml*\n\n```\n- hosts: myhosts\n gather_facts: true\n become: true\n```\n\n \n\n[Back To Top](#top)\n\n\n## Add vars key\n\nRemember, the task runner will ultimately be calling the `ansible-playbook` command against this very same file, so it must be conformant.\n\n\n We add the 'vars' key, which allows ansible to populate the variables we are defining in this block.
\n\n*Taskfile.yaml*\n\n```\n- hosts: myhosts\n gather_facts: true\n become: true\n vars:\n```\n\n \n\n[Back To Top](#top)\n\n\n## Populate the vars block - defaults\n\n\n Let's add some default variables to the playbook:
\n\n*Taskfile.yaml*\n\n```\n- hosts: myhosts\n gather_facts: true\n become: true\n vars:\n myvar1: myvalue1\n myvar2: myvalue2\n myvar3: myvalue3\n myvar4: |\n This is a multi-line value\n of type string\n myvar5:\n - mylistvalue1\n - mylistvalue2\n - mylistvalue3\n - mylistvalue4\n myvar6: $(grep somestring /some/file.txt)\n```\n\n \n\nAs you can see, we've defined a number of variables holding different values.\n\nThe rules for defining these play out as follows:\n\n```\nVariable | Ansible Evaluation | Bash Evaluation\n-------------------------------------------- | ----------------------- | -----------------------\nstr_var: myvalue1 | String | String\nnum_var: 3 | Digit | String\nmultiline_var: | | Multiline String | String (heredoc)\n This is a multi-line value\n of type string\nlist_var: | List Object | String (heredoc)\n - item1\n - item2\ndict_var: | Dictionary Object | None, Skipped # TODO Add interpolation of yaml dictionary objects for subprocess\n key1: somevalue1\n key2: somevalue2\nshell_var: $(grep somestring /some/file.txt) | Depends on output | String\n```\n\n[Back To Top](#top)\n\n\n## Populate the vars block - cli options\n\n\n Next, we add the cli interface:
\n\n*Taskfile.yaml*\n\n```\n- hosts: myhosts\n gather_facts: true\n become: true\n vars:\n myvar1: myvalue1\n myvar2: myvalue2\n myvar3: myvalue3\n myvar4: |\n This is a multi-line value\n of type string\n myvar5:\n - mylistvalue1\n - mylistvalue2\n - mylistvalue3\n - mylistvalue4\n myvar6: $(grep somestring /some/file.txt)\n required_parameters:\n -d|--db-hosts: dbhosts ## Specify DB Host targets\n -w|--web-hosts: webhosts ## Specify Web Host targets\n -t|--some-parameter: some_value ## Specify some value\n optional_parameters:\n -l|--another-parameter: another_value ## Specify another value\n -A: hello ## Invoke the 'hello' make-style function\n -PR: preflight_and_run ## Invoke the 'preflight_and_run' make-style function\n --debug-mode: debug_mode ## Enable debug mode\n``` \n\n \n\nNotice the parameter definitions:\n - required_parameters\n - optional_paramters\n\nThese are yaml list objects that expose optional and required command-line options.\n\nThe syntax for the options is as follows:\n\n```\nOptions | Mapped Variable\n-------------------------------------------- | ----------------------\n-{{ short_option }}|--{{ long_option }} | {{ mapped_variable }} ## {{ Help Text }}\n-{{ switch }} | {{ mapped_variable }} (boolean) ## {{ Help Text }}\n--{{ switch }} | {{ mapped_variable }} (boolean) ## {{ Help Text }}\n```\n\nEssentially, any option with a pipe '|' character in its name is evaluated as a click option, which means you must provide an argument to said option.\n\nAnything else is treated as a switch, which evaluates to `True` if specified, and undefined otherwise (unless you provide a default in your `vars` declaration).\n\nAlso, an option's help text can be included alongside the mapped variable, and must conform to the following syntax: `## {{ HELP TEXT }}`\n\nMore Examples:\n\n```\nOptions | Mapped Variable\n------------- | -------------\n-f|--foo | some_foo_variable ## This is some foo option\n-b|--bar | some_bar_variable ## This is some bar option\n-F|--foo-bar | some_other_variable ## This is some foo bar option\n-a|--all-else | [remaining_args] (behaves like click's variadic arguments (nargs=*)) ## This option will 'eat' up all remaining commandline arguments\n--some-option | some_switch (behaves like click switches, holds the value of True if specified) ## This is some boolean option\n```\n\nMore flexibility can be achieved through the use of [parameter sets](#parameter-sets).\n\nSee the [appendix](#parameter_sets) for more information.\n\n[Back To Top](#top)\n\n\n### Populate the vars block - cli options - mapped variables\n\nIt's important to note that the above mapped variables can be used during runtime, i.e. referenced in any defined functions, embedded inventory logic, etc.\n\nConsider the `-f|-foo` option above.\n\nWhatever argument you pass to this option becomes the value for the mapped variable.\n\nAgain, this variable is made available to the underlying subprocess call, and within the ansible playbook itself.\n\n\n\n## Populate the vars block - help/message\n\n\n Next, we add the help/message section
\n\n*Taskfile.yaml*\n\n```\n- hosts: myhosts\n gather_facts: true\n become: true\n vars:\n myvar1: myvalue1\n myvar2: myvalue2\n myvar3: myvalue3\n myvar4: |\n This is a multi-line value\n of type string\n myvar5:\n - mylistvalue1\n - mylistvalue2\n - mylistvalue3\n - mylistvalue4\n myvar6: $(grep somestring /some/file.txt)\n required_parameters:\n -d|--db-hosts: dbhosts ## Specify DB Host targets\n -w|--web-hosts: webhosts ## Specify Web Host targets\n -t|--some-parameter: some_value ## Specify some value\n optional_parameters:\n -l|--another-parameter: another_value ## Specify another value\n -A: hello ## Invoke the 'hello' make-style function\n -PR: preflight_and_run ## Invoke the 'preflight_and_run' make-style function\n --debug-mode: debug_mode ## Enable debug mode\n help:\n message: |\n Do something against db and web hosts\n epilog: |\n This line will be displayed at the end of the help text message\n examples:\n - example1: |\n Usage example 1\n - example2: |\n Usage example 2\n```\n\n \n\n[Back To Top](#top)\n\n\n## Populate the vars block - inventory\n\n\n Add the dynamic inventory section
\n\n*Taskfile.yaml*\n\n```\n- hosts: myhosts\n gather_facts: true\n become: true\n vars:\n myvar1: myvalue1\n myvar2: myvalue2\n myvar3: myvalue3\n myvar4: |\n This is a multi-line value\n of type string\n myvar5:\n - mylistvalue1\n - mylistvalue2\n - mylistvalue3\n - mylistvalue4\n myvar6: $(grep somestring /some/file.txt)\n required_parameters:\n -d|--db-hosts: dbhosts ## Specify DB Host targets\n -w|--web-hosts: webhosts ## Specify Web Host targets\n -t|--some-parameter: some_value ## Specify some value\n optional_parameters:\n -l|--another-parameter: another_value ## Specify another value\n -A: hello ## Invoke the 'hello' make-style function\n -PR: preflight_and_run ## Invoke the 'preflight_and_run' make-style function\n --debug-mode: debug_mode ## Enable debug mode\n help:\n message: |\n Do something against db and web hosts\n epilog: |\n This line will be displayed at the end of the help text message\n examples:\n - example1: |\n Usage example 1\n - example2: |\n Usage example 2\n inventory: |\n [web-hosts]\n $(echo ${webhosts} | tr ',' '\\\\n')\n [db-hosts]\n $(echo ${dbhosts} | tr ',' '\\\\n')\n [myhosts:children]\n deployment-hosts\n web-hosts\n db-hosts\n```\n\n \n\n\n\n## Populate the vars block - embedded make-style functions\n\n\n Add embedded make-style functions:
\n\n*Taskfile.yaml*\n\n```\n- hosts: myhosts\n gather_facts: true\n become: true\n vars:\n myvar1: myvalue1\n myvar2: myvalue2\n myvar3: myvalue3\n myvar4: |\n This is a multi-line value\n of type string\n myvar5:\n - mylistvalue1\n - mylistvalue2\n - mylistvalue3\n - mylistvalue4\n myvar6: $(grep somestring /some/file.txt)\n required_parameters:\n -d|--db-hosts: dbhosts ## Specify DB Host targets\n -w|--web-hosts: webhosts ## Specify Web Host targets\n -t|--some-parameter: some_value ## Specify some value\n optional_parameters:\n -l|--another-parameter: another_value ## Specify another value\n -A: hello ## Invoke the 'hello' make-style function\n -PR: preflight_and_run ## Invoke the 'preflight_and_run' make-style function\n --debug-mode: debug_mode ## Enable debug mode\n help:\n message: |\n Do something against db and web hosts\n epilog: |\n This line will be displayed at the end of the help text message\n examples:\n - example1: |\n Usage example 1\n - example2: |\n Usage example 2\n inventory: |\n [web-hosts]\n $(echo ${webhosts} | tr ',' '\\\\n')\n [db-hosts]\n $(echo ${dbhosts} | tr ',' '\\\\n')\n [myhosts:children]\n deployment-hosts\n web-hosts\n db-hosts\n functions:\n hello:\n shell: bash\n help: Say Hello\n hidden: false\n source: |-\n echo hello\n preflight_and_run:\n shell: bash\n help: Execute Preflight Tasks and Run\n hidden: false\n source: |-\n echo 'Running Preflight Tasks!'\n tasks run -d dbhost1 -w webhost1 -t value1\n```\n\n \n\nNotice the two switches `-A` and `-PR`.\n\nThese map to corresponding keys in the embedded `functions` stanza.\nAs such, specifying the options in your `tasks` invocation \nwill short-circuit normal operation and execute the corresponding functions in the order you called them.\n\nFor usage examples, see the [appendix](#usage-examples).\n\n\n\n### About make-style functions\n\nLet's briefly side-step into make-style functions \n\nThe syntax for nesting these under the _functions_ key is as follows:\n\n```\n name_of_function:\n shell: bash, ruby, or python\n help: Help Text to Display\n hidden: false/true\n source: |-\n {{ code }}\n```\n\n[Back To Top](#top)\n\n\n#### Bash example:\n\n```\n hello:\n shell: bash\n help: Hello World in Bash\n hidden: false\n source: |-\n echo 'Hello World!'\n```\n\n\n\n#### Python example:\n\n```\n hello:\n shell: python\n help: Hello World in Python\n hidden: false\n source: |-\n print('Hello World!')\n```\n\n\n\n#### Ruby example:\n\n```\n hello:\n shell: ruby\n help: Hello World in Ruby\n hidden: false\n source: |-\n puts 'Hello World!'\n```\n\n[Back To Top](#top)\n\n\n## Add tasks\n\n\n Finally, we add tasks!
\n\n*Taskfile.yaml*\n\n```\n- hosts: myhosts\n gather_facts: true\n become: true\n vars:\n myvar1: myvalue1\n myvar2: myvalue2\n myvar3: myvalue3\n myvar4: |\n This is a multi-line value\n of type string\n myvar5:\n - mylistvalue1\n - mylistvalue2\n - mylistvalue3\n - mylistvalue4\n myvar6: $(grep somestring /some/file.txt)\n required_parameters:\n -d|--db-hosts: dbhosts ## Specify DB Host targets\n -w|--web-hosts: webhosts ## Specify Web Host targets\n -t|--some-parameter: some_value ## Specify some value\n optional_parameters:\n -l|--another-parameter: another_value ## Specify another value\n -A: hello ## Invoke the 'hello' make-style function\n -PR: preflight_and_run ## Invoke the 'preflight_and_run' make-style function\n --debug-mode: debug_mode ## Enable debug mode\n help:\n message: |\n Do something against db and web hosts\n epilog: |\n This line will be displayed at the end of the help text message\n examples:\n - example1: |\n Usage example 1\n - example2: |\n Usage example 2\n inventory: |\n [web-hosts]\n $(echo ${webhosts} | tr ',' '\\\\n')\n [db-hosts]\n $(echo ${dbhosts} | tr ',' '\\\\n')\n [myhosts:children]\n deployment-hosts\n web-hosts\n db-hosts\n functions:\n hello:\n shell: bash\n help: Say Hello\n hidden: false\n source: |-\n echo hello\n tasks:\n - debug: \n msg: |\n Hello from Ansible!\n You specified: {{ some_value }}\n```\n\n \n\n\n\n# Usage Examples\n\nQuick usage examples:\n\n* Display help for main command
\n `tasks --help`\n* Display help for the *run* subcommand
\n `tasks run --help`\n* Initialize your workspace
\n `tasks init`
\n* Run the Taskfile.yaml playbook, passing in additional options to the underlying subprocess
\n `tasks run -d dbhost1 -w webhost1 -t value1 ---raw '-vvv'`\n* Don't do anything, just echo the underlying shell command
\n `tasks run -d dbhost1 -w webhost1 -t value1 ---echo`
\n Result should be similar to:
\n `ansible-playbook -i C:\\Users\\${USERNAME}\\AppData\\Local\\Temp\\ansible-inventory16xdkrjd.tmp.ini -e dbhosts=\"dbhost1\" -e webhosts=\"webhost1\" -e some_value=\"value1\" -e echo=\"True\" Taskfile.yaml`\n* Run the Taskfile.yaml playbook
\n `tasks run -d dbhost1 -w webhost1 -t value1`\n* Run the embedded function `preflight_and_run`
\n `tasks run -d dbhost1 -w webhost1 -t value1 -PR`\n* Run the embedded functions `hello` and `preflight_and_run`
\n `tasks run -d dbhost1 -w webhost1 -t value1 -A -PR`\n\n[Back To Top](#top)\n\n\n# Installation\n\nAnsible-taskrunner consists of the `tasks` binary (for now), and it can be installed in a few ways:\n\n1. pip install ansible-taskrunner\n2. pip install git+https://github.com/berttejeda/ansible-taskrunner.git\n3. Obtaining a [release](#single-executable-releases)\n\nNote: You'll need to pre-install a python distribution for the Windows MSI release.\nNot yet sure if I am doing something wrong or if that's by design.\nI lean towards the former :|\n\n\n\n## More Examples\n\nReview the [examples](examples) directory for more hands-on usage samples.\n\n\n\n# Appendix\n\n\n\n## Bastion Mode\n\nIf you're launching the `tasks` command from a Windows host, this tool will automatically execute in _Bastion Mode_\n\nUnder Bastion Mode, the `tasks` command will:\n- Execute the `ansible-playbook` subprocess via a _bastion host_, i.e. a remote machine that has `ansible` installed\n- This is done via ssh using the [paramiko](http://www.paramiko.org/) module\n\nAs you would expect, running in Bastion Mode requires a configuration file containing the ssh connection settings.\n\nTo initialize this configuration file, you can simply run `tasks init`.\n\nFor full usage options, enter in `tasks init --help`.\n\nOnce you've initialized the configuration file, you should see *sftp-config.json* in your workspace.\n\nThis configuration file is fashioned after the [sftp](https://packagecontrol.io/packages/SFTP) plugin for [Sublime Text](https://www.sublimetext.com/)\nand is thus compatible.\n\n\n\n## Special Variables\n\n\n\n### ansible_playbook_command\n\nIf you define the playbook variable *ansible_playbook_command*, this will override the underlying ansible-playbook command invocation.\n\nAs an example, suppose I define this variable in the above *Taskfile.yaml*, as follows:\n\n```\n- hosts: myhosts\n gather_facts: true\n become: true\n vars:\n ansible_playbook_command: 'python ${HOME}/ansible_2.7.8/ansible-playbook'\n myvar1: myvalue1\n myvar2: myvalue2\n myvar3: myvalue3\n # ...\n```\nUpon invoking the `tasks` command with the `---echo` flag:\n\n- The temporary inventory is revealed as:
\n\n```\nif [[ ($inventory) && ( 'True' == 'True') ]];then\necho -e \"\"\"[web-hosts]\n$(echo ${webhosts} | tr ',' '\\\\n')\n[db-hosts]\n$(echo ${dbhosts} | tr ',' '\\\\n')\n[myhosts:children]\ndeployment-hosts\nweb-hosts\ndb-hosts\n\"\"\" | while read line;do\neval \"echo -e ${line}\" >> \"C:\\Users\\${USERNAME}\\AppData\\Local\\Temp\\ansible-inventory16xdkrjd.tmp.ini\"\ndone\nfi\n```\n\n- And the underlying shell command would be revealed as:
\n\n`python ${HOME}/ansible_2.7.8/ansible-playbook -i C:\\Users\\${USERNAME}\\AppData\\Local\\Temp\\ansible-inventory16xdkrjd.tmp.ini -e dbhosts=\"dbhost1\" -e webhosts=\"webhost1\" -e some_value=\"value1\" -e echo=\"True\" Taskfile.yaml`\n\n[Back To Top](#top)\n\n\n### cli_provider\n\nYou can override the underlying command-line provider in two ways:\n\n- Via the tasks config file (see [examples](#examples))\n- By defining the variable *cli_provider* in the specified Taskfile\n\nAs an example, suppose I define this variable in the above *Taskfile.yaml*, as follows:\n\n```\n- hosts: myhosts\n gather_facts: true\n become: true\n vars:\n cli_provider: bash\n # ...\n```\n\nUpon invoking the `tasks` command, you will note that the app no longer operates in an **ansible-playbook** mode, but rather as yaml-abstracted bash-script.\n\nThere are three cli-providers built in to the tasks command:\n\n- ansible\n- bash\n- vagrant\n\n\n\n### __ansible_extra_options\n\nApart from utilizing the `---raw` flag, you can specify additional options to pass to the underlying `ansible-playbook` subprocess by setting an appropriate value for the **__ansible_extra_options** Environmental variable.\n\n\n\n### __tasks_file__\n\nThe **\\_\\_tasks_file\\_\\_** variable points to the current Taskfile.\n\nIt is available to the underlying subprocess shell.\n\n\n\n### __parameter_sets__\n\nAs explained [above](#parameter_sets), the **\\_\\_parameter_sets\\_\\_** variable tracks whatever parameter sets you've specified during runtime.\n\nThe variable will hod the values as a space-delimited string, and is available to the underlying subprocess.\n\nYou can use this behavior to detect when a given parameter set has been activated.\n\n[Back To Top](#top)\n\n\n## Parameter Sets\n\nWhat if you wanted to operate under multiple contexts?\n\ne.g. You want to be able to interact with Amazon Web Services (AWS) and Google Cloud Platform (GCP)?\n\nSure, you could add paramters to your heart's content, but you'll pollute the output from `--help`\n\nThis is where parameter sets come into play.\n\nThe functionality is simple. Precede the `run` subcommand with the keys you specify as parameter sets in your task manifest.\n\nThese words act as _mini_ subcommands, and _unlock_ the command-line options defined by the corresponding key in the appropriate options section of your manifest.\n\nHere's an example:\n\n```\n required_parameters:\n aws:\n -d|--db-hosts: dbhosts_aws ## Specify AWS DBHost\n -a|--some-special-aws-flag: aws_flag ## Specify Some Special AWS Option\n gcp:\n -d|--db-hosts: dbhosts_gcp ## Specify GCP DBHost\n -g|--some-special-gcp-flag: gcp_flag ## Specify Some Special GCP Option\n```\n\nNote the _aws_ and _gcp_ keys.\n\nYou'll notice that the output of `--help` will change depending on what parameter sets you specify, e.g.\n\n`tasks aws run --help`\n\n`tasks gcp run --help`\n\n`tasks aws gcp run --help`\n\nAnother thing to note is that the parameter set you specify is tracked during runtime as the variable _parameter_sets_\n\nYou can use this behavior to detect when a given parameter set has been activated.\n\n[Back To Top](#top)\n\n\n## Mutually Exclusive Options\n\nTaken from [Mutually exclusive option groups in python Click - Stack Overflow](https://stackoverflow.com/questions/37310718/mutually-exclusive-option-groups-in-python-click).\n\nSuppose you want a set of options such that:\n- You want to accept one option but only if another, related option has not been specified\n\nYou can accomplish this by defining your options with an ' or ' format, as with:\n\n```\n-a|--auth-token: auth_token ## Specify auth token\n-u|--username or -a|--auth-token: username ## Specify Username\n-p|--password or -a|--auth-token: password ## Specify Password\n```\n\nIn the above configuration, calling the options for \nusername and password will render the option for auth token _optional_, \nthat is, you don't need to specify the auth token if you've specified \nthe username and password.\n\nA sample is provided in the [examples](examples) directory.\n\n\n\n## Simple Templating\n\nAs of version 1.1.5, simple templating is available to the following objects:\n\n- Help messages\n- Examples\n- Options\n- Options values\n\nWhat this means is that we expose a limited set of internal variables to the above.\n\nAs an example:\n\n```\n examples:\n - example1: |\n tasks -f $tf_path --foo foo --bar bar\n - example2: |\n tasks -f $tf_path --foo foo --baz baz\n``` \n\nIn the above strings, `$tf_path` will expand to the internal variable tf_path,\nwhich holds the relative path to the current tasks file.\n\nBelow is a list of available variables for your convenience:\n\n- cli_args\n- cli_args_short\n- parameter_sets\n- tf_path\n\n```\nVariable | Description\n------------- | -------------\nexe_path | The absolute path to the tasks executable\ncli_args | The current command-line invocation\ncli_args_short | The current command-line invocation, minus the executable\nparameter_sets | The parameter sets you have invoked\nsys_platform | The OS Platform as detected by Python\ntf_path | The relative path to the specified Taskfile\n```\n\n[Back To Top](#top)\n\n\n## Single-Executable Releases\n\nThis script also ships as a zipapp executable (similar to a windows .exe).\n\nHead over to the [releases page](https://github.com/berttejeda/ansible-taskrunner/releases) for release downloads.\n\nYou can also build your own single-executable zipapp, as follows:\n\n1. Make sure you have the [make-zipapp](https://github.com/berttejeda/make-zipapp) executable in your path\n1. Invoking build tasks\n - Build zipapp: `python ansible_taskrunner/cli.py -f Makefile.yaml run ---make zipapp`\n - Build zipapp and push to remote host (via scp): `python ansible_taskrunner/cli.py -f Makefile.yaml run ---make zipapp -bp someserver.somedomain.local:/home/${USER-USERNAME}`\n\nRead More on zipapps: [zipapp \u2014 Manage executable Python zip archives \u2014 Python 3.7.4rc2 documentation](https://docs.python.org/3/library/zipapp.html)\n\n\n\n## Unit Testing\n\nTo run all tests, simply call the test script, as with:\n\n`python tests/test_ansible_taskrunner.py`\n\n# TODO - Add more tests!\n\n[Back To Top](#top)\n\n\n# License and Credits\n\nThis project adopts the the MIT distribution License.\n\n[Releases](https://github.com/berttejeda/ansible-taskrunner/releases) come bundled with the following opensource python packages:\n\n- [click](https://github.com/pallets/click), licensed under BSD-3-Clause\n- [pyYaml](https://github.com/yaml/pyyaml), licensed under MIT\n\nLastly, this package was created with Cookiecutter and the `audreyr/cookiecutter-pypackage` project template.\n\n- Cookiecutter: https://github.com/audreyr/cookiecutter\n- audreyr/cookiecutter-pypackage: https://github.com/audreyr/cookiecutter-pypackage\n\n\n",
"description_content_type": "text/markdown",
"docs_url": null,
"download_url": "",
"downloads": {
"last_day": -1,
"last_month": -1,
"last_week": -1
},
"home_page": "https://github.com/berttejeda/ansible_taskrunner",
"keywords": "ansible,playbook,wrapper,bash,python,click,task-runner,subprocess,yaml,cli,options",
"license": "",
"maintainer": "",
"maintainer_email": "",
"name": "ansible-taskrunner",
"package_url": "https://pypi.org/project/ansible-taskrunner/",
"platform": "",
"project_url": "https://pypi.org/project/ansible-taskrunner/",
"project_urls": {
"Homepage": "https://github.com/berttejeda/ansible_taskrunner"
},
"release_url": "https://pypi.org/project/ansible-taskrunner/1.3.0/",
"requires_dist": [
"click (==6.7)",
"crayons (==0.2.0)",
"PyYAML (==4.2b1)",
"paramiko (==2.6.0); sys_platform == \"win32\" or sys_platform == \"cygwin\"",
"pytest; extra == 'tests'",
"pytest-cov; extra == 'tests'",
"coveralls; extra == 'tests'",
"flake8; extra == 'tests'",
"mypy; extra == 'tests'"
],
"requires_python": ">=2.7",
"summary": "ansible-playbook wrapper with YAML-abstracted python click cli options",
"version": "1.3.0"
},
"last_serial": 5985218,
"releases": {
"0.0.18": [
{
"comment_text": "",
"digests": {
"md5": "683eaa3638e548cad95475a2f19f5dd7",
"sha256": "90b749cc6eb10682e7d1491a1523ebaf0d23e99d4618351df403b12629e315cb"
},
"downloads": -1,
"filename": "ansible_taskrunner-0.0.18-py3-none-any.whl",
"has_sig": false,
"md5_digest": "683eaa3638e548cad95475a2f19f5dd7",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">= 2.7",
"size": 26917,
"upload_time": "2019-07-23T21:58:03",
"url": "https://files.pythonhosted.org/packages/e2/de/584f9d6507877047940f726258250d3626843e8d7b7cea9b8835542d1884/ansible_taskrunner-0.0.18-py3-none-any.whl"
},
{
"comment_text": "",
"digests": {
"md5": "166148f0832bd5ef9aa93ffea62a975b",
"sha256": "5a8cbee39cf6fe32bca0208fb072df2e02f6e594369c143065ed2b5a9c6ce0d3"
},
"downloads": -1,
"filename": "ansible_taskrunner-0.0.18.tar.gz",
"has_sig": false,
"md5_digest": "166148f0832bd5ef9aa93ffea62a975b",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">= 2.7",
"size": 30997,
"upload_time": "2019-07-23T21:58:06",
"url": "https://files.pythonhosted.org/packages/68/4d/3419101992cd1c8a6f9ee0cdc9e0e108634bff16ba194547e94c4da39c3f/ansible_taskrunner-0.0.18.tar.gz"
}
],
"1.0.0": [
{
"comment_text": "",
"digests": {
"md5": "9ec9d774cd248cc3c1672fa238974773",
"sha256": "6907820a486c2bdbe106314abfbd10acc126f2ca1d9eb1beef1b9e6761b5a397"
},
"downloads": -1,
"filename": "ansible_taskrunner-1.0.0-py3-none-any.whl",
"has_sig": false,
"md5_digest": "9ec9d774cd248cc3c1672fa238974773",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">= 2.7",
"size": 28080,
"upload_time": "2019-08-02T22:31:23",
"url": "https://files.pythonhosted.org/packages/5a/88/3ad198f9789e215de1d8f303ab67833c1c9d6ffd908d62253fdc5e060095/ansible_taskrunner-1.0.0-py3-none-any.whl"
},
{
"comment_text": "",
"digests": {
"md5": "c01fbfd18a3223827f243e052d93eb15",
"sha256": "445003cc214bc0e1a898224627f7f3eb39e41ecc2cf7f86bcb54d02cd8ed06e1"
},
"downloads": -1,
"filename": "ansible_taskrunner-1.0.0.tar.gz",
"has_sig": false,
"md5_digest": "c01fbfd18a3223827f243e052d93eb15",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">= 2.7",
"size": 36756,
"upload_time": "2019-08-02T22:31:25",
"url": "https://files.pythonhosted.org/packages/64/2b/dc56b21219ed07cdc384305d8b8e23c8514b6f8f5983ba8f8a84a2cecccb/ansible_taskrunner-1.0.0.tar.gz"
}
],
"1.0.2": [
{
"comment_text": "",
"digests": {
"md5": "6f8b2778c3bd51c5f6f69b703ce6698b",
"sha256": "519ef88ea5d34b1329c68fcb63cd44d37425ff5a0fe2c87c4d8d77eda79d7cef"
},
"downloads": -1,
"filename": "ansible_taskrunner-1.0.2-py3-none-any.whl",
"has_sig": false,
"md5_digest": "6f8b2778c3bd51c5f6f69b703ce6698b",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">= 2.7",
"size": 28808,
"upload_time": "2019-09-16T13:14:33",
"url": "https://files.pythonhosted.org/packages/47/18/2393c9bf0d0c22a5ef4ea46194bc34235f2dbbb97bc83d81d089a448a5f0/ansible_taskrunner-1.0.2-py3-none-any.whl"
}
],
"1.1.10": [
{
"comment_text": "",
"digests": {
"md5": "8330818f04957d2ee3037de9d3a5cb56",
"sha256": "868f42e41647be158e395a3ba30f70fe34f5b6b5fc13aca3894db345d2c4af33"
},
"downloads": -1,
"filename": "ansible_taskrunner-1.1.10-py3-none-any.whl",
"has_sig": false,
"md5_digest": "8330818f04957d2ee3037de9d3a5cb56",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">= 2.7",
"size": 42994,
"upload_time": "2019-09-27T21:34:54",
"url": "https://files.pythonhosted.org/packages/04/ba/015038c104b9d99f4bcf7385c4a1faf50756d35028e8bc6717b9830b0462/ansible_taskrunner-1.1.10-py3-none-any.whl"
},
{
"comment_text": "",
"digests": {
"md5": "f5c3e5b177937ba14dc82652580e9cf8",
"sha256": "52e1ade7611e4f4ad185bcf3501d3f8ec0888da39a6515d740c4fa845543728a"
},
"downloads": -1,
"filename": "ansible_taskrunner-1.1.10.tar.gz",
"has_sig": false,
"md5_digest": "f5c3e5b177937ba14dc82652580e9cf8",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">= 2.7",
"size": 56203,
"upload_time": "2019-09-27T21:34:56",
"url": "https://files.pythonhosted.org/packages/9f/03/a086b4a642e8131b37477291f24e90c6f37718e4768f79ef5b5821d64bae/ansible_taskrunner-1.1.10.tar.gz"
}
],
"1.2.10": [
{
"comment_text": "",
"digests": {
"md5": "1e0f799b5a014fcdf7e96108d9601fa8",
"sha256": "40fa38e8aa80642a08159c35170f05778465aef326a8ec77a312574a731cedb1"
},
"downloads": -1,
"filename": "ansible_taskrunner-1.2.10-py2-none-any.whl",
"has_sig": false,
"md5_digest": "1e0f799b5a014fcdf7e96108d9601fa8",
"packagetype": "bdist_wheel",
"python_version": "py2",
"requires_python": ">=2.7",
"size": 48128,
"upload_time": "2019-10-11T18:41:47",
"url": "https://files.pythonhosted.org/packages/9f/b1/b9396e6850a5a8c1f5211bef8ad645546d2f1bad0f27dc4392994400ff2a/ansible_taskrunner-1.2.10-py2-none-any.whl"
},
{
"comment_text": "",
"digests": {
"md5": "be06bb80ef739a4b5935afcd596e3c8d",
"sha256": "67417dbd78006057eaa2b37ce20862b0481bf0e3e7b8111a57cb083836df56b8"
},
"downloads": -1,
"filename": "ansible_taskrunner-1.2.10.tar.gz",
"has_sig": false,
"md5_digest": "be06bb80ef739a4b5935afcd596e3c8d",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=2.7",
"size": 63872,
"upload_time": "2019-10-11T18:41:49",
"url": "https://files.pythonhosted.org/packages/65/64/e79bbaaf1121236693c427a327f4dfa54a13118ecfaa862b74ef9d57f101/ansible_taskrunner-1.2.10.tar.gz"
}
],
"1.2.8": [
{
"comment_text": "",
"digests": {
"md5": "50aac9d0b8447c473a3ab95f1e5f7303",
"sha256": "f20128fe4c6005aea6e744bf0275b1a40388407ee50a8016678e451124405c54"
},
"downloads": -1,
"filename": "ansible_taskrunner-1.2.8-py2-none-any.whl",
"has_sig": false,
"md5_digest": "50aac9d0b8447c473a3ab95f1e5f7303",
"packagetype": "bdist_wheel",
"python_version": "py2",
"requires_python": ">=2.7",
"size": 48129,
"upload_time": "2019-10-11T17:26:30",
"url": "https://files.pythonhosted.org/packages/1b/8e/026e29f8d3be84e254555d211aea758731972abe8a6d74021f180c0e675d/ansible_taskrunner-1.2.8-py2-none-any.whl"
},
{
"comment_text": "",
"digests": {
"md5": "f0a456683767837843ffbf494febfbda",
"sha256": "42763f175902a97be6eae67ff787ba6925a49b38ae48ab49e3867ce6ab63e509"
},
"downloads": -1,
"filename": "ansible_taskrunner-1.2.8-py3-none-any.whl",
"has_sig": false,
"md5_digest": "f0a456683767837843ffbf494febfbda",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=2.7",
"size": 48087,
"upload_time": "2019-10-11T17:26:32",
"url": "https://files.pythonhosted.org/packages/6d/21/2dd4b5f818e57f0b012063cf410ae9678af7b3ed800e2faa01ab15845f43/ansible_taskrunner-1.2.8-py3-none-any.whl"
},
{
"comment_text": "",
"digests": {
"md5": "7b8dc134cbd92496123b6556360a4637",
"sha256": "7e8a13faeae0297373a3538fdb70ccbec54adcb242c619a5a704b5e6dcbdd488"
},
"downloads": -1,
"filename": "ansible_taskrunner-1.2.8.tar.gz",
"has_sig": false,
"md5_digest": "7b8dc134cbd92496123b6556360a4637",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=2.7",
"size": 63665,
"upload_time": "2019-10-11T17:26:33",
"url": "https://files.pythonhosted.org/packages/30/e0/36cac0894d65797a7fb7c6ca168a0876ee30de95e88e9400b2a74146b814/ansible_taskrunner-1.2.8.tar.gz"
}
],
"1.2.9": [
{
"comment_text": "",
"digests": {
"md5": "08f861779be75bf7ca385594e6747100",
"sha256": "554bd63edff91572d5c9c6172174f2380f0d4394c3e23ff342ccc542798d6b29"
},
"downloads": -1,
"filename": "ansible_taskrunner-1.2.9-py2-none-any.whl",
"has_sig": false,
"md5_digest": "08f861779be75bf7ca385594e6747100",
"packagetype": "bdist_wheel",
"python_version": "py2",
"requires_python": ">=2.7",
"size": 48131,
"upload_time": "2019-10-11T17:51:10",
"url": "https://files.pythonhosted.org/packages/a1/0b/d3ed1ced30fa3a5f9b89d7b198e667e10da3044e00294a9eb36a7583361f/ansible_taskrunner-1.2.9-py2-none-any.whl"
},
{
"comment_text": "",
"digests": {
"md5": "16b421fb3b9923283ce8eafc5de0095b",
"sha256": "4a6e98e1c54f69be5c9535772d483dda0f32c06f9fe635535210ee713b08fbfd"
},
"downloads": -1,
"filename": "ansible_taskrunner-1.2.9.tar.gz",
"has_sig": false,
"md5_digest": "16b421fb3b9923283ce8eafc5de0095b",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=2.7",
"size": 63843,
"upload_time": "2019-10-11T17:51:13",
"url": "https://files.pythonhosted.org/packages/eb/9c/0df2fb344afac54a4a17bc1433d35e653b9f8fd09fcc43dbd8bc6d0d6ef7/ansible_taskrunner-1.2.9.tar.gz"
}
],
"1.3.0": [
{
"comment_text": "",
"digests": {
"md5": "3ff78b62be69e60bdb828fb037c20ff9",
"sha256": "17718baa1461cde90ac15c77e41a35355930b5e589780d6151fc386ea4bad198"
},
"downloads": -1,
"filename": "ansible_taskrunner-1.3.0-py2-none-any.whl",
"has_sig": false,
"md5_digest": "3ff78b62be69e60bdb828fb037c20ff9",
"packagetype": "bdist_wheel",
"python_version": "py2",
"requires_python": ">=2.7",
"size": 48718,
"upload_time": "2019-10-16T16:23:40",
"url": "https://files.pythonhosted.org/packages/8e/8f/663b6a1e491371aa0cbde122d767c6e6b83a375516b8509373a8b831da19/ansible_taskrunner-1.3.0-py2-none-any.whl"
},
{
"comment_text": "",
"digests": {
"md5": "bc109381f27537978f131215f30f457e",
"sha256": "e3901408a05ac2c8d9d491b596f9230f842fb186037a9d5b07f571d5e083df90"
},
"downloads": -1,
"filename": "ansible_taskrunner-1.3.0.tar.gz",
"has_sig": false,
"md5_digest": "bc109381f27537978f131215f30f457e",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=2.7",
"size": 64392,
"upload_time": "2019-10-16T16:23:43",
"url": "https://files.pythonhosted.org/packages/68/92/b3212f4e82a3095485caa804f1e1595a9bddddda525a72169dc04877b7bd/ansible_taskrunner-1.3.0.tar.gz"
}
]
},
"urls": [
{
"comment_text": "",
"digests": {
"md5": "3ff78b62be69e60bdb828fb037c20ff9",
"sha256": "17718baa1461cde90ac15c77e41a35355930b5e589780d6151fc386ea4bad198"
},
"downloads": -1,
"filename": "ansible_taskrunner-1.3.0-py2-none-any.whl",
"has_sig": false,
"md5_digest": "3ff78b62be69e60bdb828fb037c20ff9",
"packagetype": "bdist_wheel",
"python_version": "py2",
"requires_python": ">=2.7",
"size": 48718,
"upload_time": "2019-10-16T16:23:40",
"url": "https://files.pythonhosted.org/packages/8e/8f/663b6a1e491371aa0cbde122d767c6e6b83a375516b8509373a8b831da19/ansible_taskrunner-1.3.0-py2-none-any.whl"
},
{
"comment_text": "",
"digests": {
"md5": "bc109381f27537978f131215f30f457e",
"sha256": "e3901408a05ac2c8d9d491b596f9230f842fb186037a9d5b07f571d5e083df90"
},
"downloads": -1,
"filename": "ansible_taskrunner-1.3.0.tar.gz",
"has_sig": false,
"md5_digest": "bc109381f27537978f131215f30f457e",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=2.7",
"size": 64392,
"upload_time": "2019-10-16T16:23:43",
"url": "https://files.pythonhosted.org/packages/68/92/b3212f4e82a3095485caa804f1e1595a9bddddda525a72169dc04877b7bd/ansible_taskrunner-1.3.0.tar.gz"
}
]
}