diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md new file mode 100644 index 00000000000..eb521195646 --- /dev/null +++ b/.github/ISSUE_TEMPLATE.md @@ -0,0 +1,50 @@ + + +##### ISSUE TYPE + + - Bug Report + - Feature Idea + - Documentation Report + + +##### ANSIBLE VERSION +``` + +``` + +##### CONFIGURATION + + +##### OS / ENVIRONMENT + + +##### SUMMARY + + +##### STEPS TO REPRODUCE + + +``` + +``` + + + +##### EXPECTED RESULTS + + +##### ACTUAL RESULTS + + +``` + +``` diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 00000000000..b9a19185306 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,24 @@ +##### ISSUE TYPE + + - Feature Pull Request + - New Module Pull Request + - Bugfix Pull Request + - Docs Pull Request + +##### ANSIBLE VERSION +``` + +``` + +##### SUMMARY + + + + +``` + +``` diff --git a/.gitignore b/.gitignore index 01a802805e8..bbe61d075b9 100644 --- a/.gitignore +++ b/.gitignore @@ -31,6 +31,7 @@ docs/man/man3/* *.sublime-workspace # docsite stuff... docsite/rst/modules_by_category.rst +docsite/rst/playbooks_directives.rst docsite/rst/list_of_*.rst docsite/rst/*_module.rst docsite/*.html @@ -47,6 +48,8 @@ deb-build *.swo credentials.yml # test output +*.retry +*.out .coverage .tox results.xml diff --git a/.travis.yml b/.travis.yml index 1ff0ca118d4..83fd3673dfa 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,16 +1,25 @@ -sudo: false +dist: trusty +sudo: required +services: + - docker language: python matrix: include: - - env: TOXENV=py24 INTEGRATION=no - - env: TOXENV=py26 INTEGRATION=yes + - env: TARGET=sanity TOXENV=py24 + - env: TARGET=sanity TOXENV=py26 python: 2.6 - - env: TOXENV=py27 INTEGRATION=yes + - env: TARGET=sanity TOXENV=py27 python: 2.7 - - env: TOXENV=py34 INTEGRATION=no + - env: TARGET=sanity TOXENV=py34 python: 3.4 - - env: TOXENV=py35 INTEGRATION=no + - env: TARGET=sanity TOXENV=py35 python: 3.5 + - env: TARGET=centos6 + - env: TARGET=centos7 TARGET_OPTIONS="--volume=/sys/fs/cgroup:/sys/fs/cgroup:ro" + - env: TARGET=fedora23 TARGET_OPTIONS="--volume=/sys/fs/cgroup:/sys/fs/cgroup:ro" + - env: TARGET=fedora-rawhide TARGET_OPTIONS="--volume=/sys/fs/cgroup:/sys/fs/cgroup:ro" + - env: TARGET=ubuntu1204 + - env: TARGET=ubuntu1404 addons: apt: sources: @@ -18,15 +27,16 @@ addons: packages: - python2.4 install: - - pip install tox PyYAML Jinja2 sphinx + - pip install tox coveralls script: -# urllib2's defaults are not secure enough for us -- ./test/code-smell/replace-urlopen.sh . -- ./test/code-smell/use-compat-six.sh lib -- ./test/code-smell/boilerplate.sh -- if test x"$TOXENV" != x'py24' ; then tox ; fi -- if test x"$TOXENV" = x'py24' ; then python2.4 -V && python2.4 -m compileall -fq -x 'module_utils/(a10|rax|openstack|ec2|gce).py' lib/ansible/module_utils ; fi - #- make -C docsite all -- if test x"$INTEGRATION" = x'yes' ; then source ./hacking/env-setup && cd test/integration/ && make parsing && make test_var_precedence && make unicode ; fi + - ./test/utils/run_tests.sh after_success: - coveralls +notifications: + irc: + channels: + - "chat.freenode.net#ansible-notices" + on_success: change + on_failure: always + skip_join: true + nick: ansibletravis diff --git a/CHANGELOG.md b/CHANGELOG.md index f9f8b4b76a9..8fb7e76a6c0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,13 +3,102 @@ Ansible Changes By Release ## 2.1 TBD - ACTIVE DEVELOPMENT +###Major Changes: + +* added facility for modules to send back 'diff' for display when ansible is called with --diff, updated several modules to return this info +* added ansible-console tool, a REPL shell that allows running adhoc tasks against a chosen inventory (based on https://github.com/dominis/ansible-shell) + ####New Modules: -* cloudstack: cs_volume +- aws + * ec2_vol_facts + * ec2_vpc_dhcp_options + * ec2_vpc_net_facts +- cloudflare_dns +- cloudstack + * cs_cluster + * cs_configuration + * cs_instance_facts + * cs_pod + * cs_resourcelimit + * cs_volume + * cs_zone + * cs_zone_facts +- openstack + * os_flavor_facts + * os_group + * os_ironic_inspect + * os_keystone_role +- softlayer + * sl_vm +- windows + * win_regmerge + * win_timezone +- yum_repository + ####New Filters: * extract -## 2.0 "Over the Hills and Far Away" +####New Callbacks: +* actionable (only shows changed and failed) +* slack +* json + +####New Inventory scripts: +* rackhd + +###Minor Changes: + +* callbacks now have access to the options with which the CLI was called +* debug now has verbosity option to control when to display by matching number of -v in command line +* modules now get verbosity, diff and other flags as passed to ansible +* mount facts now also show 'network mounts' that use the pattern `:/` +* Plugins are now sorted before loading. This means, for instance, if you want + two custom callback plugins to run in a certain order you can name them + 10-first-callback.py and 20-second-callback.py. + +## 2.0.1 "Over the Hills and Far Away" + +* Fixes a major compatibility break in the synchronize module shipped with + 2.0.0.x. That version of synchronize ran sudo on the controller prior to + running rsync. In 1.9.x and previous, sudo was run on the host that rsync + connected to. 2.0.1 restores the 1.9.x behaviour. +* Additionally, several other problems with where synchronize chose to run when + combined with delegate_to were fixed. In particular, if a playbook targetted + localhost and then delegated_to a remote host the prior behavior (in 1.9.x + and 2.0.0.x) was to copy files between the src and destination directories on + the delegated host. This has now been fixed to copy between localhost and + the delegated host. +* Fix a regression where synchronize was unable to deal with unicode paths. +* Fix a regression where synchronize deals with inventory hosts that use + localhost but with an alternate port. +* Fixes a regression where the retry files feature was not implemented. +* Fixes a regression where the any_errors_fatal option was implemented in 2.0 + incorrectly, and also adds a feature where any_errors_fatal can be set at + the block level. +* Fix tracebacks when playbooks or ansible itself were located in directories + with unicode characters. +* Fix bug when sending unicode characters to an external pager for display. +* Fix a bug with squashing loops for special modules (mostly package managers). + The optimization was squashing when the loop did not apply to the selection + of packages. This has now been fixed. +* Temp files created when using vault are now "shredded" using the unix shred + program which overwrites the file with random data. +* Some fixes to cloudstack modules for case sensitivity +* Fix non-newstyle modules (non-python modules and old-style modules) to + disabled pipelining. +* Fix fetch module failing even if fail_on_missing is set to False +* Fix for cornercase when local connections, sudo, and raw were used together. +* Fix dnf module to remove dependent packages when state=absent is specified. + This was a feature of the 1.9.x version that was left out by mistake when the + module was rewritten for 2.0. +* Fix bugs with non-english locales in yum, git, and apt modules +* Fix a bug with the dnf module where state=latest could only upgrade, not install. +* Fix to make implicit fact gathering task correctly inherit settings from play, + this might cause an error if settings environment on play depending on 'ansible_env' + which was previouslly ignored + +## 2.0 "Over the Hills and Far Away" - Jan 12, 2016 ###Major Changes: @@ -32,14 +121,15 @@ Ansible Changes By Release by setting the `ANSIBLE_NULL_REPRESENTATION` environment variable. * Added `meta: refresh_inventory` to force rereading the inventory in a play. This re-executes inventory scripts, but does not force them to ignore any cache they might use. -* Now when you delegate an action that returns ansible_facts, these facts will be applied to the delegated host, unlike before when they were applied to the current host. +* New delegate_facts directive, a boolean that allows you to apply facts to the delegated host (true/yes) instead of the inventory_hostname (no/false) which is the default and previous behaviour. * local connections now work with 'su' as a privilege escalation method -* New ssh configuration variables(`ansible_ssh_common_args`, `ansible_ssh_extra_args`) can be used to configure a +* Ansible 2.0 has deprecated the “ssh” from ansible_ssh_user, ansible_ssh_host, and ansible_ssh_port to become ansible_user, ansible_host, and ansible_port. +* New ssh configuration variables (`ansible_ssh_common_args`, `ansible_ssh_extra_args`) can be used to configure a per-group or per-host ssh ProxyCommand or set any other ssh options. `ansible_ssh_extra_args` is used to set options that are accepted only by ssh (not sftp or scp, which have their own analogous settings). +* ansible-pull can now verify the code it runs when using git as a source repository, using git's code signing and verification features. * Backslashes used when specifying parameters in jinja2 expressions in YAML dicts sometimes needed to be escaped twice. This has been fixed so that escaping once works. Here's an example of how playbooks need to be modified: -* ansible-pull can now verify the code it runs when using git as a source repository, using git's code signing and verification features. ``` # Syntax in 1.9.x @@ -81,9 +171,31 @@ newline being stripped you can change your playbook like this: "msg": "Testing some things" ``` +* When specifying complex args as a variable, the variable must use the full jinja2 +variable syntax ('{{var_name}}') - bare variable names there are no longer accepted. +In fact, even specifying args with variables has been deprecated, and will not be +allowed in future versions: + + ``` + --- + - hosts: localhost + connection: local + gather_facts: false + vars: + my_dirs: + - { path: /tmp/3a, state: directory, mode: 0755 } + - { path: /tmp/3b, state: directory, mode: 0700 } + tasks: + - file: + args: "{{item}}" + with_items: my_dirs + ``` + ###Plugins * Rewritten dnf module that should be faster and less prone to encountering bugs in cornercases +* WinRM connection plugin passes all vars named `ansible_winrm_*` to the underlying pywinrm client. This allows, for instance, `ansible_winrm_server_cert_validation=ignore` to be used with newer versions of pywinrm to disable certificate validation on Python 2.7.9+. +* WinRM connection plugin put_file is significantly faster and no longer has file size limitations. ####Deprecated Modules (new ones in parens): @@ -98,196 +210,219 @@ newline being stripped you can change your playbook like this: ####New Modules: -* amazon: ec2_ami_copy -* amazon: ec2_ami_find -* amazon: ec2_elb_facts -* amazon: ec2_eni -* amazon: ec2_eni_facts -* amazon: ec2_remote_facts -* amazon: ec2_vpc_igw -* amazon: ec2_vpc_net -* amazon: ec2_vpc_route_table -* amazon: ec2_vpc_route_table_facts -* amazon: ec2_vpc_subnet -* amazon: ec2_vpc_subnet_facts -* amazon: ec2_win_password -* amazon: ecs_cluster -* amazon: ecs_task -* amazon: ecs_taskdefinition -* amazon: elasticache_subnet_group_facts -* amazon: iam -* amazon: iam_cert -* amazon: iam_policy -* amazon: route53_facts -* amazon: route53_health_check -* amazon: route53_zone -* amazon: sts_assume_role -* amazon: s3_bucket -* amazon: s3_lifecycle -* amazon: s3_logging -* amazon: sqs_queue -* amazon: sns_topic -* amazon: sts_assume_role -* apk -* bigip_gtm_wide_ip -* bundler -* centurylink: clc_aa_policy -* centurylink: clc_alert_policy -* centurylink: clc_blueprint_package -* centurylink: clc_firewall_policy -* centurylink: clc_group -* centurylink: clc_loadbalancer -* centurylink: clc_modify_server -* centurylink: clc_publicip -* centurylink: clc_server -* centurylink: clc_server_snapshot -* circonus_annotation -* consul -* consul_acl -* consul_kv -* consul_session -* cloudtrail -* cloudstack: cs_account -* cloudstack: cs_affinitygroup -* cloudstack: cs_domain -* cloudstack: cs_facts -* cloudstack: cs_firewall -* cloudstack: cs_iso -* cloudstack: cs_instance -* cloudstack: cs_instancegroup -* cloudstack: cs_ip_address -* cloudstack: cs_loadbalancer_rule -* cloudstack: cs_loadbalancer_rule_member -* cloudstack: cs_network -* cloudstack: cs_portforward -* cloudstack: cs_project -* cloudstack: cs_sshkeypair -* cloudstack: cs_securitygroup -* cloudstack: cs_securitygroup_rule -* cloudstack: cs_staticnat -* cloudstack: cs_template -* cloudstack: cs_user -* cloudstack: cs_vmsnapshot -* cronvar -* datadog_monitor -* deploy_helper -* docker: docker_login -* dpkg_selections -* elasticsearch_plugin -* expect -* find -* google: gce_tag -* hall -* ipify_facts -* iptables -* libvirt: virt_net -* libvirt: virt_pool -* maven_artifact -* openstack: os_auth -* openstack: os_client_config -* openstack: os_image -* openstack: os_image_facts -* openstack: os_floating_ip -* openstack: os_ironic -* openstack: os_ironic_node -* openstack: os_keypair -* openstack: os_network -* openstack: os_network_facts -* openstack: os_nova_flavor -* openstack: os_object -* openstack: os_port -* openstack: os_project -* openstack: os_router -* openstack: os_security_group -* openstack: os_security_group_rule -* openstack: os_server -* openstack: os_server_actions -* openstack: os_server_facts -* openstack: os_server_volume -* openstack: os_subnet -* openstack: os_subnet_facts -* openstack: os_user -* openstack: os_user_group -* openstack: os_volume -* openvswitch_db. -* osx_defaults -* pagerduty_alert -* pam_limits -* pear -* profitbricks: profitbricks -* profitbricks: profitbricks_datacenter -* profitbricks: profitbricks_nic -* profitbricks: profitbricks_volume -* profitbricks: profitbricks_volume_attachments -* profitbricks: profitbricks_snapshot -* proxmox: proxmox -* proxmox: proxmox_template -* puppet -* pushover -* pushbullet -* rax: rax_clb_ssl -* rax: rax_mon_alarm -* rax: rax_mon_check -* rax: rax_mon_entity -* rax: rax_mon_notification -* rax: rax_mon_notification_plan -* rabbitmq_binding -* rabbitmq_exchange -* rabbitmq_queue -* selinux_permissive -* sendgrid -* sensu_check -* sensu_subscription -* seport -* slackpkg -* solaris_zone -* taiga_issue -* vertica_configuration -* vertica_facts -* vertica_role -* vertica_schema -* vertica_user -* vmware: vca_fw -* vmware: vca_nat -* vmware: vmware_cluster -* vmware: vmware_datacenter -* vmware: vmware_dns_config -* vmware: vmware_dvs_host -* vmware: vmware_dvs_portgroup -* vmware: vmware_dvswitch -* vmware: vmware_host -* vmware: vmware_migrate_vmk -* vmware: vmware_portgroup -* vmware: vmware_target_canonical_facts -* vmware: vmware_vm_facts -* vmware: vmware_vm_vss_dvs_migrate -* vmware: vmware_vmkernel -* vmware: vmware_vmkernel_ip_config -* vmware: vmware_vsan_cluster -* vmware: vmware_vswitch -* vmware: vsphere_copy -* webfaction_app -* webfaction_db -* webfaction_domain -* webfaction_mailbox -* webfaction_site -* win_acl -* win_environment -* win_firewall_rule -* win_package -* win_scheduled_task -* win_iis_virtualdirectory -* win_iis_webapplication -* win_iis_webapppool -* win_iis_webbinding -* win_iis_website -* win_regedit -* win_unzip -* xenserver_facts -* zabbix_host -* zabbix_hostmacro -* zabbix_screen -* znode +- amazon + * ec2_ami_copy + * ec2_ami_find + * ec2_elb_facts + * ec2_eni + * ec2_eni_facts + * ec2_remote_facts + * ec2_vpc_igw + * ec2_vpc_net + * ec2_vpc_net_facts + * ec2_vpc_route_table + * ec2_vpc_route_table_facts + * ec2_vpc_subnet + * ec2_vpc_subnet_facts + * ec2_win_password + * ecs_cluster + * ecs_task + * ecs_taskdefinition + * elasticache_subnet_group_facts + * iam + * iam_cert + * iam_policy + * route53_facts + * route53_health_check + * route53_zone + * s3_bucket + * s3_lifecycle + * s3_logging + * sns_topic + * sqs_queue + * sts_assume_role +- apk +- bigip_gtm_wide_ip +- bundler +- centurylink + * clc_aa_policy + * clc_alert_policy + * clc_blueprint_package + * clc_firewall_policy + * clc_group + * clc_loadbalancer + * clc_modify_server + * clc_publicip + * clc_server + * clc_server_snapshot +- circonus_annotation +- consul + * consul + * consul_acl + * consul_kv + * consul_session +- cloudtrail +- cloudstack + * cs_account + * cs_affinitygroup + * cs_domain + * cs_facts + * cs_firewall + * cs_iso + * cs_instance + * cs_instancegroup + * cs_ip_address + * cs_loadbalancer_rule + * cs_loadbalancer_rule_member + * cs_network + * cs_portforward + * cs_project + * cs_securitygroup + * cs_securitygroup_rule + * cs_sshkeypair + * cs_staticnat + * cs_template + * cs_user + * cs_vmsnapshot +- cronvar +- datadog_monitor +- deploy_helper +- docker + * docker_login +- dpkg_selections +- elasticsearch_plugin +- expect +- find +- google + * gce_tag +- hall +- ipify_facts +- iptables +- libvirt + * virt_net + * virt_pool +- maven_artifact +- openstack + * os_auth + * os_client_config + * os_image + * os_image_facts + * os_floating_ip + * os_ironic + * os_ironic_node + * os_keypair + * os_network + * os_network_facts + * os_nova_flavor + * os_object + * os_port + * os_project + * os_router + * os_security_group + * os_security_group_rule + * os_server + * os_server_actions + * os_server_facts + * os_server_volume + * os_subnet + * os_subnet_facts + * os_user + * os_user_group + * os_volume +- openvswitch_db +- osx_defaults +- pagerduty_alert +- pam_limits +- pear +- profitbricks + * profitbricks + * profitbricks_datacenter + * profitbricks_nic + * profitbricks_snapshot + * profitbricks_volume + * profitbricks_volume_attachments +- proxmox + * proxmox + * proxmox_template +- puppet +- pushover +- pushbullet +- rax + * rax_clb_ssl + * rax_mon_alarm + * rax_mon_check + * rax_mon_entity + * rax_mon_notification + * rax_mon_notification_plan +- rabbitmq + * rabbitmq_binding + * rabbitmq_exchange + * rabbitmq_queue +- selinux_permissive +- sendgrid +- sensu + * sensu_check + * sensu_subscription +- seport +- slackpkg +- solaris_zone +- taiga_issue +- vertica + * vertica_configuration + * vertica_facts + * vertica_role + * vertica_schema + * vertica_user +- vmware + * vca_fw + * vca_nat + * vmware_cluster + * vmware_datacenter + * vmware_dns_config + * vmware_dvs_host + * vmware_dvs_portgroup + * vmware_dvswitch + * vmware_host + * vmware_migrate_vmk + * vmware_portgroup + * vmware_target_canonical_facts + * vmware_vm_facts + * vmware_vm_vss_dvs_migrate + * vmware_vmkernel + * vmware_vmkernel_ip_config + * vmware_vsan_cluster + * vmware_vswitch + * vsphere_copy +- webfaction + * webfaction_app + * webfaction_db + * webfaction_domain + * webfaction_mailbox + * webfaction_site +- windows + * win_acl + * win_dotnet_ngen + * win_environment + * win_firewall_rule + * win_iis_virtualdirectory + * win_iis_webapplication + * win_iis_webapppool + * win_iis_webbinding + * win_iis_website + * win_lineinfile + * win_nssm + * win_package + * win_regedit + * win_scheduled_task + * win_unzip + * win_updates + * win_webpicmd +- xenserver_facts +- zabbbix + * zabbix_host + * zabbix_hostmacro + * zabbix_screen +- znode ####New Inventory scripts: @@ -327,7 +462,7 @@ newline being stripped you can change your playbook like this: * Consolidated code from modules using urllib2 to normalize features, TLS and SNI support. * synchronize module's dest_port parameter now takes precedence over the ansible_ssh_port inventory setting. * Play output is now dynamically sized to terminal with a minimum of 80 coluumns (old default). -* vars_prompt and pause are now skipped with a warning if the play is called non interactively (i.e. pull from cron). +* vars_prompt and pause are now skipped with a warning if the play is called noninteractively (i.e. pull from cron). * Support for OpenBSD's 'doas' privilege escalation method. * Most vault operations can now be done over multilple files. * ansible-vault encrypt/decrypt read from stdin if no other input file is given, and can write to a given ``--output file`` (including stdout, '-'). @@ -338,15 +473,19 @@ newline being stripped you can change your playbook like this: * Many fixes and new options added to modules, too many to list here. * Now you can see task file and line number when using verbosity of 3 or above. * The ``[x-y]`` host range syntax is no longer supported. Note that ``[0:1]`` matches two hosts, i.e. the range is inclusive of its endpoints. -* We now recommend the Use `pattern1,pattern2` to combine host matching patterns. +* We now recommend the use of `pattern1,pattern2` to combine host matching patterns. * The use of ':' as a separator conflicts with IPv6 addresses and host ranges. It will be deprecated in the future. * The undocumented use of ';' as a separator is now deprecated. * modules and callbacks have been extended to support no_log to avoid data disclosure. -* new managed_syslog option has been added to control output to syslog on managed machines, no_log supercsedes this settings. +* new managed_syslog option has been added to control output to syslog on managed machines, no_log supersedes this settings. * Lookup, vars and action plugin pathing has been normalized, all now follow the same sequence to find relative files. * We do not ignore the explicitly set login user for ssh when it matches the 'current user' anymore, this allows overriding .ssh/config when it is set explicitly. Leaving it unset will still use the same user and respect .ssh/config. This also means ansible_ssh_user can now return a None value. -* environment variables passed to remote shells now default to 'controller' settings, with fallback to en_us.UTF8 which was the previous default. +* environment variables passed to remote shells now default to 'controller' settings, with fallback to en_US.UTF8 which was the previous default. +* add_hosts is much stricter about host name and will prevent invalid names from being added. +* ansible-pull now defaults to doing shallow checkouts with git, use `--full` to return to previous behaviour. +* random cows are more random +* when: now gets the registered var after the first iteration, making it possible to break out of item loops * Handling of undefined variables has changed. In most places they will now raise an error instead of silently injecting an empty string. Use the default filter if you want to approximate the old behaviour: ``` @@ -456,19 +595,19 @@ Major changes: New Modules: -* cryptab: manages linux encrypted block devices -* gce_img: for utilizing GCE image resources -* gluster_volume: manage glusterfs volumes -* haproxy: for the load balancer of same name -* known_hosts: manages the ssh known_hosts file -* lxc_container: manage lxc containers -* patch: allows for patching files on target systems -* pkg5: installing and uninstalling packages on Solaris -* pkg5_publisher: manages Solaris pkg5 repository configuration -* postgresql_ext: manage postgresql extensions -* snmp_facts: gather facts via snmp -* svc: manages daemontools based services -* uptimerobot: manage monitoring with this service +* cryptab *-- manages linux encrypted block devices* +* gce_img *-- for utilizing GCE image resources* +* gluster_volume *-- manage glusterfs volumes* +* haproxy *-- for the load balancer of same name* +* known_hosts *-- manages the ssh known_hosts file* +* lxc_container *-- manage lxc containers* +* patch *-- allows for patching files on target systems* +* pkg5 *-- installing and uninstalling packages on Solaris* +* pkg5_publisher *-- manages Solaris pkg5 repository configuration* +* postgresql_ext *-- manage postgresql extensions* +* snmp_facts *-- gather facts via snmp* +* svc *-- manages daemontools based services* +* uptimerobot *-- manage monitoring with this service* New Filters: @@ -604,15 +743,19 @@ Major changes: New Modules: -* cloud: rax_cdb - manages Rackspace Cloud Database instances -* cloud: rax_cdb_database - manages Rackspace Cloud Databases -* cloud: rax_cdb_user - manages Rackspace Cloud Database users -* monitoring: zabbix_maintaince - handles outage windows with Zabbix -* monitoring: bigpanda - support for bigpanda -* net_infrastructure: a10_server - manages server objects on A10 devices -* net_infrastructure: a10_service_group - manages service group objects on A10 devices -* net_infrastructure: a10_virtual_server - manages virtual server objects on A10 devices -* system: getent - read getent databases +- cloud + * rax_cdb *-- manages Rackspace Cloud Database instances* + * rax_cdb_database *-- manages Rackspace Cloud Databases* + * rax_cdb_user *-- manages Rackspace Cloud Database users* +- monitoring + * bigpanda *-- support for bigpanda* + * zabbix_maintaince *-- handles outage windows with Zabbix* +- net_infrastructure + * a10_server *-- manages server objects on A10 devices* + * a10_service_group *-- manages service group objects on A10 devices* + * a10_virtual_server *-- manages virtual server objects on A10 devices* +- system + * getent *-- read getent databases* Some other notable changes: @@ -691,19 +834,21 @@ New inventory scripts: New Modules: -* cloud: azure -* cloud: rax_meta -* cloud: rax_scaling_group -* cloud: rax_scaling_policy -* windows: version of setup module -* windows: version of slurp module -* windows: win_feature -* windows: win_get_url -* windows: win_msi -* windows: win_ping -* windows: win_user -* windows: win_service -* windows: win_group +- cloud + * azure + * rax_meta + * rax_scaling_group + * rax_scaling_policy +- windows + * *version of setup module* + * *version of slurp module* + * win_feature + * win_get_url + * win_group + * win_msi + * win_ping + * win_service + * win_user Other notable changes: @@ -786,40 +931,48 @@ Major features/changes: New Modules: -* files: replace -* packaging: cpanm (Perl) -* packaging: portage -* packaging: composer (PHP) -* packaging: homebrew_tap (OS X) -* packaging: homebrew_cask (OS X) -* packaging: apt_rpm -* packaging: layman -* monitoring: logentries -* monitoring: rollbar_deployment -* monitoring: librato_annotation -* notification: nexmo (SMS) -* notification: twilio (SMS) -* notification: slack (Slack.com) -* notification: typetalk (Typetalk.in) -* notification: sns (Amazon) -* system: debconf -* system: ufw -* system: locale_gen -* system: alternatives -* system: capabilities -* net_infrastructure: bigip_facts -* net_infrastructure: dnssimple -* net_infrastructure: lldp -* web_infrastructure: apache2_module -* cloud: digital_ocean_domain -* cloud: digital_ocean_sshkey -* cloud: rax_identity -* cloud: rax_cbs (cloud block storage) -* cloud: rax_cbs_attachments -* cloud: ec2_asg (configure autoscaling groups) -* cloud: ec2_scaling_policy -* cloud: ec2_metric_alarm -* cloud: vsphere_guest +- files + * replace +- packaging + * apt_rpm + * composer *(PHP)* + * cpanm *(Perl)* + * homebrew_cask *(OS X)* + * homebrew_tap *(OS X)* + * layman + * portage +- monitoring + * librato_annotation + * logentries + * rollbar_deployment +- notification + * nexmo *(SMS)* + * slack *(Slack.com)* + * sns *(Amazon)* + * twilio *(SMS)* + * typetalk *(Typetalk.in)* +- system + * alternatives + * capabilities + * debconf + * locale_gen + * ufw +- net_infrastructure + * bigip_facts + * dnssimple + * lldp +- web_infrastructure + * apache2_module +- cloud + * digital_ocean_domain + * digital_ocean_sshkey + * ec2_asg *(configure autoscaling groups)* + * ec2_metric_alarm + * ec2_scaling_policy + * rax_identity + * rax_cbs *(cloud block storage)* + * rax_cbs_attachments + * vsphere_guest Other notable changes: @@ -829,7 +982,7 @@ Other notable changes: * libvirt module now supports destroyed and paused as states * s3 module can specify metadata * security token additions to ec2 modules -* setup module code moved into module_utils/, facts now accessible by other modules +* setup module code moved into module_utils/, facts now accessible by other modules * synchronize module sets relative dirs based on inventory or role path * misc bugfixes and other parameters * the ec2_key module now has wait/wait_timeout parameters @@ -842,7 +995,6 @@ Other notable changes: * the get_url module now accepts url_username and url_password as parameters, so sites which require authentication no longer need to have them embedded in the url * ... to be filled in from changelogs ... -* ## 1.5.5 "Love Walks In" - April 18, 2014 @@ -879,7 +1031,7 @@ Major features/changes: * only_if, which is much older than when_foo and was deprecated, is similarly removed. * ssh connection plugin is now more efficient if you add 'pipelining=True' in ansible.cfg under [ssh_connection], see example.cfg * localhost/127.0.0.1 is not required to be in inventory if referenced, if not in inventory, it does not implicitly appear in the 'all' group. -* git module has new parameters (accept_hostkey, key_file, ssh_opts) to ease the usage of git and ssh protocols. +* git module has new parameters (accept_hostkey, key_file, ssh_opts) to ease the usage of git and ssh protocols. * when using accelerate mode, the daemon will now be restarted when specifying a different remote_user between plays. * added no_log: option for tasks. When used, no logging information will be sent to syslog during the module execution. * acl module now handles 'default' and allows for either shorthand entry or specific fields per entry section @@ -888,24 +1040,28 @@ Major features/changes: * all ec2 modules that work with Eucalyptus also now support a 'validate_certs' option, which can be set to 'off' for installations using self-signed certs. * Start of new integration test infrastructure (WIP, more details TBD) * if repoquery is unavailable, the yum module will automatically attempt to install yum-utils -* ansible-vault: a framework for encrypting your playbooks and variable files +* ansible-vault: a framework for encrypting your playbooks and variable files * added support for privilege escalation via 'su' into bin/ansible and bin/ansible-playbook and associated keywords 'su', 'su_user', 'su_pass' for tasks/plays New modules: -* cloud: ec2_elb_lb -* cloud: ec2_key -* cloud: ec2_snapshot -* cloud: rax_dns -* cloud: rax_dns_record -* cloud: rax_files -* cloud: rax_files_objects -* cloud: rax_keypair -* cloud: rax_queue -* cloud: docker_image -* messaging: rabbitmq_policy -* system: at -* utilities: assert +- cloud + * docker_image + * ec2_elb_lb + * ec2_key + * ec2_snapshot + * rax_dns + * rax_dns_record + * rax_files + * rax_files_objects + * rax_keypair + * rax_queue +- messaging + * rabbitmq_policy +- system + * at +- utilities + * assert Other notable changes (many new module params & bugfixes may not be listed): @@ -984,43 +1140,52 @@ Highlighted new features: New modules and plugins. -* cloud: ec2_eip -- manage AWS elastic IPs -* cloud: ec2_vpc -- manage ec2 virtual private clouds -* cloud: elasticcache -- Manages clusters in Amazon Elasticache -* cloud: rax_network -- sets up Rackspace networks -* cloud: rax_facts: retrieve facts about a Rackspace Cloud Server -* cloud: rax_clb_nodes -- manage Rackspace cloud load balanced nodes -* cloud: rax_clb -- manages Rackspace cloud load balancers -* cloud: docker - instantiates/removes/manages docker containers -* cloud: ovirt -- VM lifecycle controls for ovirt -* files: acl -- set or get acls on a file -* files: unarchive: pushes and extracts tarballs -* files: synchronize: a useful wraper around rsyncing trees of files -* system: firewalld -- manage the firewalld configuration -* system: modprobe -- manage kernel modules on systems that support modprobe/rmmod -* system: open_iscsi -- manage targets on an initiator using open-iscsi -* system: blacklist: add or remove modules from the kernel blacklist -* system: hostname - sets the systems hostname -* utilities: include_vars -- dynamically load variables based on conditions. -* packaging: zypper_repository - adds or removes Zypper repositories -* packaging: urpmi - work with urpmi packages -* packaging: swdepot - a module for working with swdepot -* notification: grove - notifies to Grove hosted IRC channels -* web_infrastructure: ejabberd_user: add and remove users to ejabberd -* web_infrastructure: jboss: deploys or undeploys apps to jboss -* source_control: github_hooks: manages GitHub service hooks -* net_infrastructure: bigip_monitor_http: manages F5 BIG-IP LTM http monitors -* net_infrastructure: bigip_monitor_tcp: manages F5 BIG-IP LTM TCP monitors -* net_infrastructure: bigip_pool_member: manages F5 BIG-IP LTM pool members -* net_infrastructure: bigip_node: manages F5 BIG-IP LTM nodes -* net_infrastructure: openvswitch_port -* net_infrastructure: openvswitch_bridge +- cloud + * docker *- instantiates/removes/manages docker containers* + * ec2_eip *-- manage AWS elastic IPs* + * ec2_vpc *-- manage ec2 virtual private clouds* + * elasticcache *-- Manages clusters in Amazon Elasticache* + * ovirt *-- VM lifecycle controls for ovirt* + * rax_network *-- sets up Rackspace networks* + * rax_facts *-- retrieve facts about a Rackspace Cloud Server* + * rax_clb_nodes *-- manage Rackspace cloud load balanced nodes* + * rax_clb *-- manages Rackspace cloud load balancers* +- files + * acl *-- set or get acls on a file* + * synchronize *-- a useful wraper around rsyncing trees of files* + * unarchive *-- pushes and extracts tarballs* +- system + * blacklist *-- add or remove modules from the kernel blacklist* + * firewalld *-- manage the firewalld configuration* + * hostname *-- sets the systems hostname* + * modprobe *-- manage kernel modules on systems that support modprobe/rmmod* + * open_iscsi *-- manage targets on an initiator using open-iscsi* +- utilities + * include_vars *-- dynamically load variables based on conditions.* +- packaging + * swdepot *-- a module for working with swdepot* + * urpmi *-- work with urpmi packages* + * zypper_repository *-- adds or removes Zypper repositories* +- notification + * grove *-- notifies to Grove hosted IRC channels* +- web_infrastructure + * ejabberd_user *-- add and remove users to ejabberd* + * jboss *-- deploys or undeploys apps to jboss* +- source_control + * github_hooks *-- manages GitHub service hooks* +- net_infrastructure + * bigip_monitor_http *-- manages F5 BIG-IP LTM http monitors* + * bigip_monitor_tcp *-- manages F5 BIG-IP LTM TCP monitors* + * bigip_node *-- manages F5 BIG-IP LTM nodes* + * bigip_pool_member *-- manages F5 BIG-IP LTM pool members* + * openvswitch_port + * openvswitch_bridge Plugins: * jail connection module (FreeBSD) * lxc connection module -* added inventory script for listing FreeBSD jails +* added inventory script for listing FreeBSD jails * added md5 as a Jinja2 filter: {{ path | md5 }} * added a fileglob filter that will return files matching a glob pattern. with_items: "/foo/pattern/*.txt | fileglob" * 'changed' filter returns whether a previous step was changed easier. when: registered_result | changed @@ -1035,7 +1200,7 @@ Misc changes (all module additions/fixes may not listed): * Added `ansible_env` to the list of facts returned by the setup module. * Added `state=touch` to the file module, which functions similarly to the command-line version of `touch`. * Added a -vvvv level, which will show SSH client debugging information in the event of a failure. -* Includes now support the more standard syntax, similar to that of role includes and dependencies. +* Includes now support the more standard syntax, similar to that of role includes and dependencies. * Changed the `user:` parameter on plays to `remote_user:` to prevent confusion with the module of the same name. Still backwards compatible on play parameters. * Added parameter to allow the fetch module to skip the md5 validation step ('validate_md5=false'). This is useful when fetching files that are actively being written to, such as live log files. * Inventory hosts are used in the order they appear in the inventory. @@ -1117,26 +1282,35 @@ Highlighted new features: New modules: -* notifications: datadog_event -- send data to datadog -* cloud: digital_ocean -- module for DigitalOcean provisioning that also includes inventory support -* cloud: rds -- Amazon Relational Database Service -* cloud: linode -- modules for Linode provisioning that also includes inventory support -* cloud: route53 -- manage Amazon DNS entries -* cloud: ec2_ami -- manages (and creates!) ec2 AMIs -* database: mysql_replication -- manages mysql replication settings for masters/slaves -* database: mysql_variables -- manages mysql runtime variables -* database: redis -- manages redis databases (slave mode and flushing data) -* net_infrastructure: arista_interface -* net_infrastructure: arista_lag -* net_infrastructure: arista_l2interface -* net_infrastructure: arista_vlan -* system: stat -- reports on stat(istics) of remote files, for use with 'register' -* web_infrastructure: htpasswd -- manipulate htpasswd files -* packaging: rpm_key -- adds or removes RPM signing keys -* packaging: apt_repository -- rewritten to remove dependencies -* monitoring: boundary_meter -- adds or removes boundary.com meters -* net_infrastructure: dnsmadeeasy - manipulate DNS Made Easy records -* files: xattr -- manages extended attributes on files +- notifications + * datadog_event *-- send data to datadog* +- cloud + * digital_ocean *-- module for DigitalOcean provisioning that also includes inventory support* + * rds *-- Amazon Relational Database Service* + * linode *-- modules for Linode provisioning that also includes inventory support* + * route53 *-- manage Amazon DNS entries* + * ec2_ami *-- manages (and creates!) ec2 AMIs* +- database + * mysql_replication *-- manages mysql replication settings for masters/slaves* + * mysql_variables *-- manages mysql runtime variables* + * redis *-- manages redis databases (slave mode and flushing data)* +- net_infrastructure + * arista_interface + * arista_l2interface + * arista_lag + * arista_vlan + * dnsmadeeasy *-- manipulate DNS Made Easy records* +- system + * stat *-- reports on stat(istics) of remote files, for use with 'register'* +- web_infrastructure + * htpasswd *-- manipulate htpasswd files* +- packaging + * apt_repository *-- rewritten to remove dependencies* + * rpm_key *-- adds or removes RPM signing keys* +- monitoring + * boundary_meter *-- adds or removes boundary.com meters* +- files + * xattr *-- manages extended attributes on files* Misc changes: @@ -1290,40 +1464,48 @@ increasing the ease at which things can be reorganized. Modules added: -* cloud: rax: module for creating instances in the rackspace cloud (uses pyrax) -* packages: npm: node.js package management -* packages: pkgng: next-gen package manager for FreeBSD -* packages: redhat_subscription: manage Red Hat subscription usage -* packages: rhn_register: basic RHN registration -* packages: zypper (SuSE) -* database: postgresql_priv: manages postgresql privileges -* networking: bigip_pool: load balancing with F5s -* networking: ec2_elb: add and remove machines from ec2 elastic load balancers -* notification: hipchat: send notification events to hipchat -* notification: flowdock: send messages to flowdock during playbook runs -* notification: campfire: send messages to campfire during playbook runs -* notification: mqtt: send messages to the Mosquitto message bus -* notification: irc: send messages to IRC channels -* notification: filesystem - a wrapper around mkfs -* notification: jabber: send jabber chat messages -* notification: osx_say: make OS X say things out loud -* openstack: keystone_user -* openstack: glance_image -* openstack: nova_compute -* openstack: nova_keypair -* openstack: quantum_floating_ip -* openstack: quantum_floating_ip_associate -* openstack: quantum_network -* openstack: quantum_router -* openstack: quantum_router_gateway -* openstack: quantum_router_interface -* openstack: quantum_subnet -* monitoring: newrelic_deployment: notifies newrelic of new deployments -* monitoring: airbrake_deployment - notify airbrake of new deployments -* monitoring: pingdom -* monitoring: pagerduty -* monitoring: monit -* utility: set_fact: sets a variable, which can be the result of a template evaluation +- cloud + * rax *-- module for creating instances in the rackspace cloud (uses pyrax)* +- packages + * npm *-- node.js package management* + * pkgng *-- next-gen package manager for FreeBSD* + * redhat_subscription *-- manage Red Hat subscription usage* + * rhn_register *-- basic RHN registration* + * zypper *(SuSE)* +- database + * postgresql_priv *-- manages postgresql privileges* +- networking + * bigip_pool *-- load balancing with F5s* + * ec2_elb *-- add and remove machines from ec2 elastic load balancers* +- notification + * hipchat *-- send notification events to hipchat* + * flowdock *-- send messages to flowdock during playbook runs* + * campfire *-- send messages to campfire during playbook runs* + * mqtt *-- send messages to the Mosquitto message bus* + * irc *-- send messages to IRC channels* + * filesystem *-- a wrapper around mkfs* + * jabber *-- send jabber chat messages* + * osx_say *-- make OS X say things out loud* +- openstack + * glance_image + * nova_compute + * nova_keypair + * keystone_user + * quantum_floating_ip + * quantum_floating_ip_associate + * quantum_network + * quantum_router + * quantum_router_gateway + * quantum_router_interface + * quantum_subnet +- monitoring + * airbrake_deployment *-- notify airbrake of new deployments* + * monit + * newrelic_deployment *-- notifies newrelic of new deployments* + * pagerduty + * pingdom +- utility + * set_fact *-- sets a variable, which can be the result of a template evaluation* Modules removed @@ -1416,26 +1598,26 @@ Core Features Modules Added: -* bzr (bazaar version control) +* bzr *(bazaar version control)* * cloudformation * django-manage -* gem (ruby gems) +* gem *(ruby gems)* * homebrew -* lvg (logical volume groups) -* lvol (LVM logical volumes) +* lvg *(logical volume groups)* +* lvol *(LVM logical volumes)* * macports * mongodb_user * netscaler * okg * openbsd_pkg +* rabbit_mq_parameter * rabbit_mq_plugin * rabbit_mq_user * rabbit_mq_vhost -* rabbit_mq_parameter * rhn_channel -* s3 -- allows putting file contents in buckets for sharing over s3 -* uri module -- can get/put/post/etc -* vagrant -- launching VMs with vagrant, this is different from existing vagrant plugin +* s3 *-- allows putting file contents in buckets for sharing over s3* +* uri module *-- can get/put/post/etc* +* vagrant *-- launching VMs with vagrant, this is different from existing vagrant plugin* * zfs Bugfixes and Misc Changes: @@ -1537,12 +1719,12 @@ Plugins: New modules: -* new sysctl module -* new pacman module (Arch linux) -* new apt_key module -* hg module now in core -* new ec2_facts module -* added pkgin module for Joyent SmartOS +* apt_key +* ec2_facts +* hg *(now in core)* +* pacman *(Arch linux)* +* pkgin *(Joyent SmartOS)* +* sysctl New config settings: @@ -2029,4 +2211,3 @@ in kickstarts ## 0.0.2 and 0.0.1 * Initial stages of project - diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 58f495cd533..2860c3ca7fc 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,27 +1,29 @@ -Welcome To Ansible GitHub -========================= +# WELCOME TO ANSIBLE GITHUB Hi! Nice to see you here! -If you'd like to ask a question -=============================== -Please see [this web page ](http://docs.ansible.com/community.html) for community information, which includes pointers on how to ask questions on the [mailing lists](http://docs.ansible.com/community.html#mailing-list-information) and IRC. +## QUESTIONS ? -The github issue tracker is not the best place for questions for various reasons, but both IRC and the mailing list are very helpful places for those things, and that page has the pointers to those. +Please see the [community page](http://docs.ansible.com/community.html) for information on how to ask questions on the [mailing lists](http://docs.ansible.com/community.html#mailing-list-information) and IRC. -If you'd like to contribute code -================================ +The GitHub issue tracker is not the best place for questions for various reasons, but both IRC and the mailing list are very helpful places for those things, as the community page explains best. -Please see [this web page](http://docs.ansible.com/community.html) for information about the contribution process. Important license agreement information is also included on that page. -If you'd like to file a bug -=========================== +## CONTRIBUTING ? -I'd also read the community page above, but in particular, make sure you copy [this issue template](https://github.com/ansible/ansible/blob/devel/ISSUE_TEMPLATE.md) into your ticket description. We have a friendly neighborhood bot that will remind you if you forget :) This template helps us organize tickets faster and prevents asking some repeated questions, so it's very helpful to us and we appreciate your help with it. +Please see the [community page](http://docs.ansible.com/community.html) for information regarding the contribution process. Important license agreement information is also included on that page. -Also please make sure you are testing on the latest released version of Ansible or the development branch. + +## BUG TO REPORT ? + +First and foremost, also check the [community page](http://docs.ansible.com/community.html). + +You can report bugs or make enhancement requests at the [Ansible GitHub issue page](http://github.com/ansible/ansible/issues/new) by filling out the issue template that will be presented. + +Also please make sure you are testing on the latest released version of Ansible or the development branch. You can find the latest releases and development branch at: + +- https://github.com/ansible/ansible/releases +- https://github.com/ansible/ansible/archive/devel.tar.gz Thanks! - - diff --git a/ISSUE_TEMPLATE.md b/ISSUE_TEMPLATE.md deleted file mode 100644 index 094501db906..00000000000 --- a/ISSUE_TEMPLATE.md +++ /dev/null @@ -1,39 +0,0 @@ -##### Issue Type: - -Can you help us out in labelling this by telling us what kind of ticket this this? You can say: - - Bug Report - - Feature Idea - - Feature Pull Request - - New Module Pull Request - - Bugfix Pull Request - - Documentation Report - - Docs Pull Request - -##### Ansible Version: - -Let us know what version of Ansible you are using. Please supply the verbatim output from running “ansible --version”. If you're filing a ticket on a version of Ansible which is not the latest, we'd greatly appreciate it if you could retest on the latest version first. We don't expect you to test against the development branch most of the time, but we may ask for that if you have cycles. Thanks! - -##### Ansible Configuration: - -What have you changed about your Ansible installation? What configuration settings have you changed/added/removed? Compare your /etc/ansible/ansible.cfg against a clean version from Github and let us know what's different. - -##### Environment: - -What OS are you running Ansible from and what OS are you managing? Examples include RHEL 5/6, Centos 5/6, Ubuntu 12.04/13.10, *BSD, Solaris. If this is a generic feature request or it doesn’t apply, just say “N/A”. Not all tickets may be about operating system related things and we understand that. - -##### Summary: - -Please summarize your request in this space. You will earn bonus points for being succinct, but please add enough detail so we can understand the request. Thanks! - -##### Steps To Reproduce: - -If this is a bug ticket, please enter the steps you use to reproduce the problem in the space below. If this is a feature request, please enter the steps you would use to use the feature. If an example playbook is useful, please include a short reproducer inline, indented by four spaces. If a longer one is necessary, linking to one uploaded to gist.github.com would be great. Much appreciated! - -##### Expected Results: - -Please enter your expected results in this space. When running the steps supplied above in the previous section, what did you expect to happen? If showing example output, please indent your output by four spaces so it will render correctly in GitHub's viewer thingy. - -##### Actual Results: - -Please enter your actual results in this space. When running the steps supplied above, what actually happened? If you are showing example output, please indent your output by four spaces so it will render correctly in GitHub. Thanks again! - diff --git a/MANIFEST.in b/MANIFEST.in index d8402f0297f..a5e29c9a433 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -4,12 +4,14 @@ prune ticket_stubs prune packaging prune test prune hacking -include README.md packaging/rpm/ansible.spec COPYING +include README.md COPYING include examples/hosts include examples/ansible.cfg include lib/ansible/module_utils/powershell.ps1 recursive-include lib/ansible/modules * +recursive-include lib/ansible/galaxy/data * recursive-include docs * +recursive-include packaging * include Makefile include VERSION include MANIFEST.in diff --git a/Makefile b/Makefile index ac4c07f4314..367987affce 100644 --- a/Makefile +++ b/Makefile @@ -44,7 +44,7 @@ GIT_HASH := $(shell git log -n 1 --format="%h") GIT_BRANCH := $(shell git rev-parse --abbrev-ref HEAD | sed 's/[-_.\/]//g') GITINFO = .$(GIT_HASH).$(GIT_BRANCH) else -GITINFO = '' +GITINFO = "" endif ifeq ($(shell echo $(OS) | egrep -c 'Darwin|FreeBSD|OpenBSD'),1) @@ -167,6 +167,9 @@ install: sdist: clean docs $(PYTHON) setup.py sdist +sdist_upload: clean docs + $(PYTHON) setup.py sdist upload 2>&1 |tee upload.log + rpmcommon: $(MANPAGES) sdist @mkdir -p rpm-build @cp dist/*.gz rpm-build/ diff --git a/README.md b/README.md index cec8ccca971..2e1f15559d3 100644 --- a/README.md +++ b/README.md @@ -55,3 +55,4 @@ Ansible was created by [Michael DeHaan](https://github.com/mpdehaan) (michael.de Ansible is sponsored by [Ansible, Inc](http://ansible.com) + diff --git a/RELEASES.txt b/RELEASES.txt index cd32b0cddb0..871624a2595 100644 --- a/RELEASES.txt +++ b/RELEASES.txt @@ -4,11 +4,13 @@ Ansible Releases at a Glance Active Development ++++++++++++++++++ -2.0 "Over the Hills and Far Away" - in progress +2.1 "TBD" - in progress Released ++++++++ +2.0.1 "Over the Hills and Far Away" 02-24-2016 +2.0.0 "Over the Hills and Far Away" 01-12-2016 1.9.4 "Dancing In the Streets" 10-09-2015 1.9.3 "Dancing In the Streets" 09-03-2015 1.9.2 "Dancing In the Streets" 06-24-2015 diff --git a/ROADMAP.md b/ROADMAP.md new file mode 100644 index 00000000000..4d4b95b8dd5 --- /dev/null +++ b/ROADMAP.md @@ -0,0 +1,98 @@ +Roadmap For Ansible by Red Hat +============= +This document is now the location for published Ansible Core roadmaps. + +The roadmap will be updated by version. Based on team and community feedback, an initial roadmap will be published for a major or minor version (2.0, 2.1). Subminor versions will generally not have roadmaps published. + +This is the first time Ansible has published this and asked for feedback in this manner. So feedback on the roadmap and the new process is quite welcome. The team is aiming for further transparency and better inclusion of both community desires and submissions. + +These roadmaps are the team's *best guess* roadmaps based on the Ansible team's experience and are also based on requests and feedback from the community. There are things that may not make it on due to time constraints, lack of community maintainers, etc. And there may be things that got missed, so each roadmap is published both as an idea of what is upcoming in Ansible, and as a medium for seeking further feedback from the community. Here are the good places for you to submit feedback: + + * Ansible's google-group: ansible-devel + * Ansible Fest conferences. + * IRC freenode channel: #ansible-devel (this one may have things lost in lots of conversation, so a caution). + +2.1 Roadmap, Targeted for the End of April +========== +## Windows, General +* Figuring out privilege escalation (runas w/ username/password) +* Implement kerberos encryption over http +* pywinrm conversion to requests (Some mess here on pywinrm/requests. will need docs etc.) +* NTLM support + +## Modules +* Windows + * Finish cleaning up tests and support for post-beta release + * Strict mode cleanup (one module in core) + * Domain user/group management + * Finish win\_host and win\_rm in the domain/workgroup modules. + * Close 2 existing PRs (These were deemed insufficient) + * Replicate python module API in PS/C# (deprecate hodgepodge of stuff from module_utils/powershell.ps1) +* Network + * Cisco modules (ios, iosxr, nxos, iosxe) + * Arista modules (eos) + * Juniper modules (junos) + * OpenSwitch + * Cumulus + * Dell (os10) - At risk + * Netconf shared module + * Hooks for supporting Tower credentials +* VMware (This one is a little at risk due to staffing. We're investigating some community maintainers and shifting some people at Ansible around, but it is a VERY high priority). + * vsphere\_guest brought to parity with other vmware modules (vs Viasat and 'whereismyjetpack' provided modules) + * VMware modules moved to official pyvmomi bindings + * VMware inventory script updates for pyvmomi, adding tagging support +* Azure (Notes: This is on hold until Microsoft swaps out the code generator on the Azure Python SDK, which may introduce breaking changes. We have basic modules working against all of these resources at this time. Could ship it against current SDK, but may break. Or should the version be pinned?) + * Minimal Azure coverage using new ARM api + * Resource Group + * Virtual Network + * Subnet + * Public IP + * Network Interface + * Storage Account + * Security Group + * Virtual Machine + * Update of inventory script to use new API, adding tagging support +* Docker: + * Start Docker module refactor + * Update to match current docker CLI capabilities + * Docker exec support +* Upgrade other cloud modules or work with community maintainers to upgrade. (In order) + * AWS (Community maintainers) + * Openstack (Community maintainers) + * Google (Google/Community) + * Digital Ocean (Community) +* Ziploader: + * Write code to create the zipfile that gets passed across the wire to be run on the remote python + * Port most of the functionality in module\_utils to be usage in ziploader instead + * Port a few essential modules to use ziploader instead of module-replacer as proof of concept + * New modules will be able to use ziploader. Old modules will need to be ported in future releases (Some modules will not need porting but others will) + * Better testing of modules, caching of modules clientside(Have not yet arrived at an architecture for this that we like), better code sharing between ansible/ansible and modules + * ziploader is a helpful building block for: python3 porting(high priority), better code sharing between modules(medium priority) + * ziploader is a good idea before: enabling users to have custom module_utils directories +* Expand module diff support (already in progress in devel) + * Framework done. Need to add to modules, test etc. + * Coordinate with community to update their modules +* Things being kicking down the road that we said we’d do + * NOT remerging core with ansible/ansible this release cycle +* Community stuff + * Define the process/ETA for reviewing PR’s from community + * Publish better docs and how-tos for submitting code/features/fixes + + + + + + + + + + + + + + + + + + + diff --git a/VERSION b/VERSION index 879b416e609..7ec1d6db408 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2.1 +2.1.0 diff --git a/ansible-core-sitemap.xml b/ansible-core-sitemap.xml new file mode 100644 index 00000000000..84a048d3116 --- /dev/null +++ b/ansible-core-sitemap.xml @@ -0,0 +1,2716 @@ + + + + + + http://docs.ansible.com/ansible/ + weekly + 1.0 + + + http://docs.ansible.com/ansible/intro_patterns.html + weekly + 0.5 + + + http://docs.ansible.com/ansible/intro_adhoc.html + weekly + 0.5 + + + http://docs.ansible.com/ansible/intro_configuration.html + weekly + 0.5 + + + http://docs.ansible.com/ansible/intro_getting_started.html + weekly + 0.5 + + + http://docs.ansible.com/ansible/intro.html + weekly + 0.5 + + + http://docs.ansible.com/ansible/intro_inventory.html + weekly + 0.5 + + + http://docs.ansible.com/ansible/intro_installation.html + weekly + 0.5 + + + http://docs.ansible.com/ansible/intro_bsd.html + weekly + 0.5 + + + http://docs.ansible.com/ansible/intro_dynamic_inventory.html + weekly + 0.5 + + + http://docs.ansible.com/ansible/intro_windows.html + weekly + 0.5 + + + http://docs.ansible.com/ansible/playbooks_filters.html + weekly + 0.5 + + + http://docs.ansible.com/ansible/playbooks_conditionals.html + weekly + 0.5 + + + http://docs.ansible.com/ansible/playbooks.html + weekly + 0.5 + + + http://docs.ansible.com/ansible/quickstart.html + weekly + 0.5 + + + http://docs.ansible.com/ansible/playbooks_loops.html + weekly + 0.5 + + + http://docs.ansible.com/ansible/playbooks_variables.html + weekly + 0.5 + + + http://docs.ansible.com/ansible/playbooks_roles.html + weekly + 0.5 + + + http://docs.ansible.com/ansible/playbooks_intro.html + weekly + 0.5 + + + http://docs.ansible.com/ansible/playbooks_blocks.html + weekly + 0.5 + + + http://docs.ansible.com/ansible/playbooks_async.html + weekly + 0.5 + + + http://docs.ansible.com/ansible/playbooks_checkmode.html + weekly + 0.5 + + + http://docs.ansible.com/ansible/become.html + weekly + 0.5 + + + http://docs.ansible.com/ansible/playbooks_acceleration.html + weekly + 0.5 + + + http://docs.ansible.com/ansible/playbooks_best_practices.html + weekly + 0.5 + + + http://docs.ansible.com/ansible/playbooks_delegation.html + weekly + 0.5 + + + http://docs.ansible.com/ansible/playbooks_special_topics.html + weekly + 0.5 + + + http://docs.ansible.com/ansible/playbooks_strategies.html + weekly + 0.5 + + + http://docs.ansible.com/ansible/playbooks_environment.html + weekly + 0.5 + + + http://docs.ansible.com/ansible/playbooks_error_handling.html + weekly + 0.5 + + + http://docs.ansible.com/ansible/modules.html + weekly + 0.5 + + + http://docs.ansible.com/ansible/playbooks_prompts.html + weekly + 0.5 + + + http://docs.ansible.com/ansible/modules_intro.html + weekly + 0.5 + + + http://docs.ansible.com/ansible/playbooks_tags.html + weekly + 0.5 + + + http://docs.ansible.com/ansible/playbooks_lookups.html + weekly + 0.5 + + + http://docs.ansible.com/ansible/playbooks_vault.html + weekly + 0.5 + + + http://docs.ansible.com/ansible/playbooks_startnstep.html + weekly + 0.5 + + + http://docs.ansible.com/ansible/modules_core.html + weekly + 0.5 + + + http://docs.ansible.com/ansible/modules_extra.html + weekly + 0.5 + + + http://docs.ansible.com/ansible/list_of_commands_modules.html + weekly + 0.5 + + + http://docs.ansible.com/ansible/common_return_values.html + weekly + 0.5 + + + http://docs.ansible.com/ansible/modules_by_category.html + weekly + 0.5 + + + http://docs.ansible.com/ansible/list_of_cloud_modules.html + weekly + 0.5 + + + http://docs.ansible.com/ansible/list_of_all_modules.html + weekly + 0.5 + + + http://docs.ansible.com/ansible/list_of_clustering_modules.html + weekly + 0.5 + + + http://docs.ansible.com/ansible/list_of_database_modules.html + weekly + 0.5 + + + http://docs.ansible.com/ansible/list_of_files_modules.html + weekly + 0.5 + + + http://docs.ansible.com/ansible/list_of_inventory_modules.html + weekly + 0.5 + + + http://docs.ansible.com/ansible/list_of_source_control_modules.html + weekly + 0.5 + + + http://docs.ansible.com/ansible/list_of_system_modules.html + weekly + 0.5 + + + http://docs.ansible.com/ansible/list_of_utilities_modules.html + weekly + 0.5 + + + http://docs.ansible.com/ansible/list_of_monitoring_modules.html + weekly + 0.5 + + + http://docs.ansible.com/ansible/list_of_notification_modules.html + weekly + 0.5 + + + http://docs.ansible.com/ansible/list_of_messaging_modules.html + weekly + 0.5 + + + http://docs.ansible.com/ansible/list_of_network_modules.html + weekly + 0.5 + + + http://docs.ansible.com/ansible/list_of_packaging_modules.html + weekly + 0.5 + + + http://docs.ansible.com/ansible/list_of_web_infrastructure_modules.html + weekly + 0.5 + + + http://docs.ansible.com/ansible/guide_cloudstack.html + weekly + 0.5 + + + http://docs.ansible.com/ansible/guide_vagrant.html + weekly + 0.5 + + + http://docs.ansible.com/ansible/guides.html + weekly + 0.5 + + + http://docs.ansible.com/ansible/guide_gce.html + weekly + 0.5 + + + http://docs.ansible.com/ansible/list_of_windows_modules.html + weekly + 0.5 + + + http://docs.ansible.com/ansible/guide_aws.html + weekly + 0.5 + + + http://docs.ansible.com/ansible/guide_rax.html + weekly + 0.5 + + + http://docs.ansible.com/ansible/guide_rolling_upgrade.html + weekly + 0.5 + + + http://docs.ansible.com/ansible/developing.html + weekly + 0.5 + + + http://docs.ansible.com/ansible/developing_releases.html + weekly + 0.5 + + + http://docs.ansible.com/ansible/tower.html + weekly + 0.5 + + + http://docs.ansible.com/ansible/developing_inventory.html + weekly + 0.5 + + + http://docs.ansible.com/ansible/developing_test_pr.html + weekly + 0.5 + + + http://docs.ansible.com/ansible/developing_plugins.html + weekly + 0.5 + + + http://docs.ansible.com/ansible/community.html + weekly + 0.5 + + + http://docs.ansible.com/ansible/developing_api.html + weekly + 0.5 + + + http://docs.ansible.com/ansible/developing_modules.html + weekly + 0.5 + + + http://docs.ansible.com/ansible/test_strategies.html + weekly + 0.5 + + + http://docs.ansible.com/ansible/glossary.html + weekly + 0.5 + + + http://docs.ansible.com/ansible/galaxy.html + weekly + 0.5 + + + http://docs.ansible.com/ansible/faq.html + weekly + 0.5 + + + http://docs.ansible.com/ansible/YAMLSyntax.html + weekly + 0.5 + + + http://docs.ansible.com/ansible/index.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/command_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/shell_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/playbooks_filters_ipaddr.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/expect_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/script_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/raw_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/znode_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/xenserver_facts_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/cloudtrail_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/cloudformation_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/dynamodb_table_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/ec2_ami_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/ec2_ami_copy_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/ec2_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/ec2_elb_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/ec2_ami_find_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/ec2_eip_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/ec2_elb_facts_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/ec2_asg_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/ec2_eni_facts_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/ec2_elb_lb_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/ec2_eni_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/ec2_facts_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/ec2_group_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/ec2_key_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/ec2_lc_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/ec2_tag_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/ec2_scaling_policy_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/ec2_metric_alarm_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/ec2_snapshot_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/ec2_remote_facts_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/ec2_vpc_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/ec2_vol_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/ec2_vpc_igw_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/ec2_vpc_subnet_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/ec2_vpc_net_facts_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/ec2_vpc_net_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/ec2_vpc_route_table_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/ec2_win_password_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/ec2_vpc_route_table_facts_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/ec2_vpc_subnet_facts_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/ecs_cluster_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/iam_cert_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/ecs_taskdefinition_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/ecs_task_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/elasticache_subnet_group_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/iam_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/elasticache_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/iam_policy_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/rds_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/route53_zone_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/rds_subnet_group_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/route53_health_check_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/route53_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/rds_param_group_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/route53_facts_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/s3_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/sts_assume_role_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/s3_bucket_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/s3_lifecycle_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/sns_topic_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/s3_logging_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/sqs_queue_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/azure_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/clc_aa_policy_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/clc_modify_server_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/clc_alert_policy_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/clc_group_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/clc_publicip_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/clc_firewall_policy_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/clc_blueprint_package_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/clc_loadbalancer_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/clc_server_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/cs_firewall_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/cs_instance_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/clc_server_snapshot_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/cs_facts_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/cs_affinitygroup_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/cs_domain_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/cs_account_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/cs_instancegroup_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/cs_iso_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/cs_project_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/cs_ip_address_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/cs_securitygroup_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/cs_loadbalancer_rule_member_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/cs_loadbalancer_rule_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/cs_network_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/cs_portforward_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/cs_securitygroup_rule_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/cs_sshkeypair_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/cs_template_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/cs_staticnat_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/digital_ocean_domain_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/cs_vmsnapshot_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/digital_ocean_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/cs_volume_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/cs_user_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/docker_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/digital_ocean_sshkey_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/docker_login_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/gce_net_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/gce_pd_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/gc_storage_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/docker_image_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/gce_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/gce_lb_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/gce_img_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/gce_tag_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/linode_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/virt_net_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/virt_pool_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/os_auth_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/ovirt_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/lxc_container_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/virt_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/proxmox_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/proxmox_template_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/os_client_config_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/os_floating_ip_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/os_network_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/os_networks_facts_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/os_image_facts_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/os_ironic_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/os_image_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/os_ironic_node_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/os_keypair_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/os_nova_flavor_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/os_security_group_rule_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/os_server_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/os_server_actions_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/os_object_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/os_project_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/os_security_group_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/os_server_facts_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/os_router_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/os_port_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/os_server_volume_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/profitbricks_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/profitbricks_datacenter_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/os_subnets_facts_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/os_subnet_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/os_volume_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/os_user_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/os_user_group_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/profitbricks_nic_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/rax_cdb_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/rax_cdb_database_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/profitbricks_volume_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/profitbricks_volume_attachments_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/rax_cbs_attachments_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/rax_cdb_user_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/rax_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/rax_cbs_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/rax_facts_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/rax_files_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/rax_files_objects_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/rax_clb_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/rax_dns_record_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/rax_clb_nodes_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/rax_dns_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/rax_identity_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/rax_mon_entity_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/rax_mon_notification_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/rax_mon_notification_plan_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/rax_clb_ssl_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/rax_meta_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/rax_keypair_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/rax_mon_check_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/rax_network_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/rax_mon_alarm_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/rax_queue_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/rax_scaling_group_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/vca_vapp_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/vca_nat_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/rax_scaling_policy_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/vca_fw_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/vmware_dvswitch_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/vmware_cluster_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/vmware_host_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/vmware_dns_config_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/vmware_datacenter_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/vmware_dvs_host_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/vmware_dvs_portgroup_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/vmware_target_canonical_facts_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/vmware_migrate_vmk_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/vmware_vmkernel_ip_config_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/vmware_vswitch_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/vsphere_copy_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/vmware_vm_shell_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/vmware_vsan_cluster_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/vmware_vmkernel_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/vmware_vm_vss_dvs_migrate_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/vsphere_guest_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/zypper_repository_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/a10_server_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/a10_service_group_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/webfaction_db_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/webfaction_domain_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/a10_virtual_server_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/webfaction_app_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/webfaction_site_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/webfaction_mailbox_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/accelerate_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/apache2_module_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/apt_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/acl_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/alternatives_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/airbrake_deployment_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/add_host_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/apt_key_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/apk_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/at_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/authorized_key_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/apt_repository_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/assemble_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/apt_rpm_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/assert_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/async_status_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/bigip_gtm_wide_ip_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/bigip_pool_member_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/bigip_facts_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/bigip_monitor_http_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/bigpanda_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/bower_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/bigip_monitor_tcp_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/bigip_node_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/bigip_pool_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/bundler_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/boundary_meter_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/blockinfile_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/consul_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/consul_acl_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/consul_kv_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/campfire_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/composer_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/bzr_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/circonus_annotation_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/capabilities_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/consul_session_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/datadog_event_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/datadog_monitor_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/debconf_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/copy_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/cronvar_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/cpanm_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/cron_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/debug_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/crypttab_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/deploy_helper_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/django_manage_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/dnf_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/dpkg_selections_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/dnsmadeeasy_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/dnsimple_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/fail_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/easy_install_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/fetch_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/ec2_ami_search_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/ejabberd_user_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/filesystem_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/facter_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/elasticsearch_plugin_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/firewalld_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/file_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/get_url_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/find_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/flowdock_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/git_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/fireball_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/gem_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/getent_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/gluster_volume_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/github_hooks_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/hall_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/hg_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/glance_image_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/hipchat_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/group_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/grove_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/group_by_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/haproxy_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/homebrew_cask_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/homebrew_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/ini_file_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/homebrew_tap_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/irc_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/hostname_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/htpasswd_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/include_vars_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/ipify_facts_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/jabber_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/iptables_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/known_hosts_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/jboss_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/librato_annotation_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/kernel_blacklist_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/keystone_user_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/jira_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/layman_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/lvol_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/lineinfile_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/macports_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/logentries_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/locale_gen_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/lvg_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/maven_artifact_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/lldp_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/mail_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/mqtt_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/modprobe_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/mount_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/mongodb_user_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/mysql_user_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/monit_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/mysql_db_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/mysql_replication_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/mysql_variables_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/nmcli_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/netscaler_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/nagios_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/newrelic_deployment_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/nexmo_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/nova_compute_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/openvswitch_bridge_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/openvswitch_db_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/openvswitch_port_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/ohai_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/npm_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/open_iscsi_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/openbsd_pkg_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/opkg_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/nova_keypair_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/pagerduty_alert_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/pam_limits_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/patch_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/osx_say_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/pacman_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/osx_defaults_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/package_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/pagerduty_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/pause_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/pkg5_publisher_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/pear_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/pkgin_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/pingdom_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/pkg5_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/ping_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/pip_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/pkgutil_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/postgresql_lang_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/pkgng_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/portage_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/postgresql_privs_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/portinstall_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/pushbullet_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/postgresql_db_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/postgresql_ext_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/puppet_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/postgresql_user_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/quantum_network_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/pushover_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/quantum_router_interface_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/quantum_floating_ip_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/quantum_floating_ip_associate_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/rabbitmq_binding_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/quantum_router_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/quantum_router_gateway_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/rabbitmq_policy_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/quantum_subnet_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/rabbitmq_vhost_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/rabbitmq_plugin_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/rabbitmq_exchange_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/rabbitmq_queue_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/rabbitmq_parameter_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/redhat_subscription_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/rabbitmq_user_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/riak_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/rpm_key_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/seboolean_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/rollbar_deployment_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/redis_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/rhn_channel_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/rhn_register_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/replace_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/selinux_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/set_fact_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/setup_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/slack_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/sendgrid_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/seport_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/slackpkg_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/sensu_check_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/service_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/selinux_permissive_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/stat_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/subversion_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/slurp_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/supervisorctl_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/solaris_zone_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/sns_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/stackdriver_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/svr4pkg_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/snmp_facts_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/svc_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/twilio_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/swdepot_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/unarchive_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/template_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/sysctl_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/synchronize_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/uptimerobot_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/typetalk_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/ufw_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/uri_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/vertica_role_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/urpmi_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/vertica_facts_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/user_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/vertica_user_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/vertica_configuration_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/vertica_schema_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/win_dotnet_ngen_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/wait_for_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/win_feature_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/win_copy_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/win_chocolatey_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/win_firewall_rule_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/win_environment_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/win_acl_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/win_file_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/win_get_url_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/win_iis_webbinding_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/win_lineinfile_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/win_msi_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/win_iis_webapplication_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/win_iis_website_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/win_iis_virtualdirectory_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/win_iis_webapppool_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/win_group_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/win_nssm_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/win_stat_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/win_template_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/win_unzip_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/win_ping_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/win_package_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/win_regedit_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/win_updates_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/win_service_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/win_scheduled_task_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/win_user_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/zabbix_group_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/zabbix_hostmacro_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/win_webpicmd_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/xattr_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/yum_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/yumrepo_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/zabbix_host_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/zabbix_maintenance_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/zypper_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/zabbix_screen_module.html + weekly + 0.3 + + + http://docs.ansible.com/ansible/zfs_module.html + weekly + 0.3 + + + \ No newline at end of file diff --git a/bin/ansible b/bin/ansible index 7e1aa01a932..a02c5bc1745 100755 --- a/bin/ansible +++ b/bin/ansible @@ -40,6 +40,7 @@ from ansible.errors import AnsibleError, AnsibleOptionsError, AnsibleParserError from ansible.utils.display import Display from ansible.utils.unicode import to_unicode + ######################################## ### OUTPUT OF LAST RESORT ### class LastResort(object): @@ -60,6 +61,7 @@ if __name__ == '__main__': try: display = Display() + display.debug("starting run") sub = None try: @@ -107,7 +109,7 @@ if __name__ == '__main__': have_cli_options = cli is not None and cli.options is not None display.error("Unexpected Exception: %s" % to_unicode(e), wrap_text=False) if not have_cli_options or have_cli_options and cli.options.verbosity > 2: - display.display("the full traceback was:\n\n%s" % traceback.format_exc()) + display.display(u"the full traceback was:\n\n%s" % to_unicode(traceback.format_exc())) else: display.display("to see the full traceback, use -vvv") sys.exit(250) diff --git a/bin/ansible-console b/bin/ansible-console new file mode 120000 index 00000000000..cabb1f519aa --- /dev/null +++ b/bin/ansible-console @@ -0,0 +1 @@ +ansible \ No newline at end of file diff --git a/contrib/inventory/cloudstack.py b/contrib/inventory/cloudstack.py index 5911f662c94..e818aea8cff 100755 --- a/contrib/inventory/cloudstack.py +++ b/contrib/inventory/cloudstack.py @@ -109,11 +109,11 @@ class CloudStackInventory(object): project_id = self.get_project_id(options.project) if options.host: - data = self.get_host(options.host) + data = self.get_host(options.host, project_id) print(json.dumps(data, indent=2)) elif options.list: - data = self.get_list() + data = self.get_list(project_id) print(json.dumps(data, indent=2)) else: print("usage: --list | --host [--project ]", diff --git a/contrib/inventory/digital_ocean.ini b/contrib/inventory/digital_ocean.ini index 01afe33968d..b809554b20f 100644 --- a/contrib/inventory/digital_ocean.ini +++ b/contrib/inventory/digital_ocean.ini @@ -26,3 +26,9 @@ cache_max_age = 300 # Use the private network IP address instead of the public when available. # use_private_network = False + +# Pass variables to every group, e.g.: +# +# group_variables = { 'ansible_user': 'root' } +# +group_variables = {} diff --git a/contrib/inventory/digital_ocean.py b/contrib/inventory/digital_ocean.py index 1c0ef68cff4..8eeeba8de67 100755 --- a/contrib/inventory/digital_ocean.py +++ b/contrib/inventory/digital_ocean.py @@ -137,6 +137,7 @@ import re import argparse from time import time import ConfigParser +import ast try: import json @@ -168,6 +169,7 @@ class DigitalOceanInventory(object): self.cache_path = '.' self.cache_max_age = 0 self.use_private_network = False + self.group_variables = {} # Read settings, environment variables, and CLI arguments self.read_settings() @@ -261,6 +263,10 @@ or environment variables (DO_API_TOKEN)''') if config.has_option('digital_ocean', 'use_private_network'): self.use_private_network = config.get('digital_ocean', 'use_private_network') + # Group variables + if config.has_option('digital_ocean', 'group_variables'): + self.group_variables = ast.literal_eval(config.get('digital_ocean', 'group_variables')) + def read_environment(self): ''' Reads the settings from environment variables ''' # Setup credentials @@ -359,22 +365,24 @@ or environment variables (DO_API_TOKEN)''') else: dest = droplet['ip_address'] - self.inventory[droplet['id']] = [dest] - self.push(self.inventory, droplet['name'], dest) - self.push(self.inventory, 'region_' + droplet['region']['slug'], dest) - self.push(self.inventory, 'image_' + str(droplet['image']['id']), dest) - self.push(self.inventory, 'size_' + droplet['size']['slug'], dest) + dest = { 'hosts': [ dest ], 'vars': self.group_variables } + + self.inventory[droplet['id']] = dest + self.inventory[droplet['name']] = dest + self.inventory['region_' + droplet['region']['slug']] = dest + self.inventory['image_' + str(droplet['image']['id'])] = dest + self.inventory['size_' + droplet['size']['slug']] = dest image_slug = droplet['image']['slug'] if image_slug: - self.push(self.inventory, 'image_' + self.to_safe(image_slug), dest) + self.inventory['image_' + self.to_safe(image_slug)] = dest else: image_name = droplet['image']['name'] if image_name: - self.push(self.inventory, 'image_' + self.to_safe(image_name), dest) + self.inventory['image_' + self.to_safe(image_name)] = dest - self.push(self.inventory, 'distro_' + self.to_safe(droplet['image']['distribution']), dest) - self.push(self.inventory, 'status_' + droplet['status'], dest) + self.inventory['distro_' + self.to_safe(droplet['image']['distribution'])] = dest + self.inventory['status_' + droplet['status']] = dest def load_droplet_variables_for_host(self): diff --git a/contrib/inventory/ec2.ini b/contrib/inventory/ec2.ini index 1231c9d4665..0ee7f2fb471 100644 --- a/contrib/inventory/ec2.ini +++ b/contrib/inventory/ec2.ini @@ -29,17 +29,32 @@ regions_exclude = us-gov-west-1,cn-north-1 # in the event of a collision. destination_variable = public_dns_name +# This allows you to override the inventory_name with an ec2 variable, instead +# of using the destination_variable above. Addressing (aka ansible_ssh_host) +# will still use destination_variable. Tags should be written as 'tag_TAGNAME'. +#hostname_variable = tag_Name + # For server inside a VPC, using DNS names may not make sense. When an instance # has 'subnet_id' set, this variable is used. If the subnet is public, setting # this to 'ip_address' will return the public IP address. For instances in a # private subnet, this should be set to 'private_ip_address', and Ansible must # be run from within EC2. The key of an EC2 tag may optionally be used; however # the boto instance variables hold precedence in the event of a collision. -# WARNING: - instances that are in the private vpc, _without_ public ip address +# WARNING: - instances that are in the private vpc, _without_ public ip address # will not be listed in the inventory until You set: -# vpc_destination_variable = 'private_ip_address' +# vpc_destination_variable = private_ip_address vpc_destination_variable = ip_address +# The following two settings allow flexible ansible host naming based on a +# python format string and a comma-separated list of ec2 tags. Note that: +# +# 1) If the tags referenced are not present for some instances, empty strings +# will be substituted in the format string. +# 2) This overrides both destination_variable and vpc_destination_variable. +# +#destination_format = {0}.{1}.example.com +#destination_format_tags = Name,environment + # To tag instances on EC2 with the resource records that point to them from # Route53, uncomment and set 'route53' to True. route53 = False @@ -144,7 +159,7 @@ group_by_elasticache_replication_group = True # You can use wildcards in filter values also. Below will list instances which # tag Name value matches webservers1* -# (ex. webservers15, webservers1a, webservers123 etc) +# (ex. webservers15, webservers1a, webservers123 etc) # instance_filters = tag:Name=webservers1* # A boto configuration profile may be used to separate out credentials diff --git a/contrib/inventory/ec2.py b/contrib/inventory/ec2.py index 4c5cf23fcb8..f0214b61f06 100755 --- a/contrib/inventory/ec2.py +++ b/contrib/inventory/ec2.py @@ -237,6 +237,19 @@ class Ec2Inventory(object): self.destination_variable = config.get('ec2', 'destination_variable') self.vpc_destination_variable = config.get('ec2', 'vpc_destination_variable') + if config.has_option('ec2', 'hostname_variable'): + self.hostname_variable = config.get('ec2', 'hostname_variable') + else: + self.hostname_variable = None + + if config.has_option('ec2', 'destination_format') and \ + config.has_option('ec2', 'destination_format_tags'): + self.destination_format = config.get('ec2', 'destination_format') + self.destination_format_tags = config.get('ec2', 'destination_format_tags').split(',') + else: + self.destination_format = None + self.destination_format_tags = None + # Route53 self.route53_enabled = config.getboolean('ec2', 'route53') self.route53_excluded_zones = [] @@ -318,8 +331,14 @@ class Ec2Inventory(object): if not os.path.exists(cache_dir): os.makedirs(cache_dir) - self.cache_path_cache = cache_dir + "/ansible-ec2.cache" - self.cache_path_index = cache_dir + "/ansible-ec2.index" + cache_name = 'ansible-ec2' + aws_profile = lambda: (self.boto_profile or + os.environ.get('AWS_PROFILE') or + os.environ.get('AWS_ACCESS_KEY_ID')) + if aws_profile(): + cache_name = '%s-%s' % (cache_name, aws_profile()) + self.cache_path_cache = cache_dir + "/%s.cache" % cache_name + self.cache_path_index = cache_dir + "/%s.index" % cache_name self.cache_max_age = config.getint('ec2', 'cache_max_age') if config.has_option('ec2', 'expand_csv_tags'): @@ -388,7 +407,10 @@ class Ec2Inventory(object): # Instance filters (see boto and EC2 API docs). Ignore invalid filters. self.ec2_instance_filters = defaultdict(list) if config.has_option('ec2', 'instance_filters'): - for instance_filter in config.get('ec2', 'instance_filters', '').split(','): + + filters = [f for f in config.get('ec2', 'instance_filters').split(',') if f] + + for instance_filter in filters: instance_filter = instance_filter.strip() if not instance_filter or '=' not in instance_filter: continue @@ -407,7 +429,7 @@ class Ec2Inventory(object): help='Get all the variables about a specific instance') parser.add_argument('--refresh-cache', action='store_true', default=False, help='Force refresh of cache by making API requests to EC2 (default: False - use cache files)') - parser.add_argument('--boto-profile', action='store', + parser.add_argument('--profile', '--boto-profile', action='store', dest='boto_profile', help='Use boto profile for connections to EC2') self.args = parser.parse_args() @@ -491,9 +513,14 @@ class Ec2Inventory(object): try: conn = self.connect_to_aws(rds, region) if conn: - instances = conn.get_all_dbinstances() - for instance in instances: - self.add_rds_instance(instance, region) + marker = None + while True: + instances = conn.get_all_dbinstances(marker=marker) + marker = instances.marker + for instance in instances: + self.add_rds_instance(instance, region) + if not marker: + break except boto.exception.BotoServerError as e: error = e.reason @@ -511,7 +538,7 @@ class Ec2Inventory(object): # that's why we need to call describe directly (it would be called by # the shorthand method anyway...) try: - conn = elasticache.connect_to_region(region) + conn = self.connect_to_aws(elasticache, region) if conn: # show_cache_node_info = True # because we also want nodes' information @@ -547,7 +574,7 @@ class Ec2Inventory(object): # that's why we need to call describe directly (it would be called by # the shorthand method anyway...) try: - conn = elasticache.connect_to_region(region) + conn = self.connect_to_aws(elasticache, region) if conn: response = conn.describe_replication_groups() @@ -615,7 +642,9 @@ class Ec2Inventory(object): return # Select the best destination address - if instance.subnet_id: + if self.destination_format and self.destination_format_tags: + dest = self.destination_format.format(*[ getattr(instance, 'tags').get(tag, '') for tag in self.destination_format_tags ]) + elif instance.subnet_id: dest = getattr(instance, self.vpc_destination_variable, None) if dest is None: dest = getattr(instance, 'tags').get(self.vpc_destination_variable, None) @@ -628,32 +657,46 @@ class Ec2Inventory(object): # Skip instances we cannot address (e.g. private VPC subnet) return + # Set the inventory name + hostname = None + if self.hostname_variable: + if self.hostname_variable.startswith('tag_'): + hostname = instance.tags.get(self.hostname_variable[4:], None) + else: + hostname = getattr(instance, self.hostname_variable) + + # If we can't get a nice hostname, use the destination address + if not hostname: + hostname = dest + + hostname = self.to_safe(hostname).lower() + # if we only want to include hosts that match a pattern, skip those that don't - if self.pattern_include and not self.pattern_include.match(dest): + if self.pattern_include and not self.pattern_include.match(hostname): return # if we need to exclude hosts that match a pattern, skip those - if self.pattern_exclude and self.pattern_exclude.match(dest): + if self.pattern_exclude and self.pattern_exclude.match(hostname): return # Add to index - self.index[dest] = [region, instance.id] + self.index[hostname] = [region, instance.id] # Inventory: Group by instance ID (always a group of 1) if self.group_by_instance_id: - self.inventory[instance.id] = [dest] + self.inventory[instance.id] = [hostname] if self.nested_groups: self.push_group(self.inventory, 'instances', instance.id) # Inventory: Group by region if self.group_by_region: - self.push(self.inventory, region, dest) + self.push(self.inventory, region, hostname) if self.nested_groups: self.push_group(self.inventory, 'regions', region) # Inventory: Group by availability zone if self.group_by_availability_zone: - self.push(self.inventory, instance.placement, dest) + self.push(self.inventory, instance.placement, hostname) if self.nested_groups: if self.group_by_region: self.push_group(self.inventory, region, instance.placement) @@ -662,28 +705,28 @@ class Ec2Inventory(object): # Inventory: Group by Amazon Machine Image (AMI) ID if self.group_by_ami_id: ami_id = self.to_safe(instance.image_id) - self.push(self.inventory, ami_id, dest) + self.push(self.inventory, ami_id, hostname) if self.nested_groups: self.push_group(self.inventory, 'images', ami_id) # Inventory: Group by instance type if self.group_by_instance_type: type_name = self.to_safe('type_' + instance.instance_type) - self.push(self.inventory, type_name, dest) + self.push(self.inventory, type_name, hostname) if self.nested_groups: self.push_group(self.inventory, 'types', type_name) # Inventory: Group by key pair if self.group_by_key_pair and instance.key_name: key_name = self.to_safe('key_' + instance.key_name) - self.push(self.inventory, key_name, dest) + self.push(self.inventory, key_name, hostname) if self.nested_groups: self.push_group(self.inventory, 'keys', key_name) # Inventory: Group by VPC if self.group_by_vpc_id and instance.vpc_id: vpc_id_name = self.to_safe('vpc_id_' + instance.vpc_id) - self.push(self.inventory, vpc_id_name, dest) + self.push(self.inventory, vpc_id_name, hostname) if self.nested_groups: self.push_group(self.inventory, 'vpcs', vpc_id_name) @@ -692,7 +735,7 @@ class Ec2Inventory(object): try: for group in instance.groups: key = self.to_safe("security_group_" + group.name) - self.push(self.inventory, key, dest) + self.push(self.inventory, key, hostname) if self.nested_groups: self.push_group(self.inventory, 'security_groups', key) except AttributeError: @@ -712,7 +755,7 @@ class Ec2Inventory(object): key = self.to_safe("tag_" + k + "=" + v) else: key = self.to_safe("tag_" + k) - self.push(self.inventory, key, dest) + self.push(self.inventory, key, hostname) if self.nested_groups: self.push_group(self.inventory, 'tags', self.to_safe("tag_" + k)) if v: @@ -722,20 +765,21 @@ class Ec2Inventory(object): if self.route53_enabled and self.group_by_route53_names: route53_names = self.get_instance_route53_names(instance) for name in route53_names: - self.push(self.inventory, name, dest) + self.push(self.inventory, name, hostname) if self.nested_groups: self.push_group(self.inventory, 'route53', name) # Global Tag: instances without tags if self.group_by_tag_none and len(instance.tags) == 0: - self.push(self.inventory, 'tag_none', dest) + self.push(self.inventory, 'tag_none', hostname) if self.nested_groups: self.push_group(self.inventory, 'tags', 'tag_none') # Global Tag: tag all EC2 instances - self.push(self.inventory, 'ec2', dest) + self.push(self.inventory, 'ec2', hostname) - self.inventory["_meta"]["hostvars"][dest] = self.get_host_info_dict_from_instance(instance) + self.inventory["_meta"]["hostvars"][hostname] = self.get_host_info_dict_from_instance(instance) + self.inventory["_meta"]["hostvars"][hostname]['ansible_ssh_host'] = dest def add_rds_instance(self, instance, region): @@ -753,24 +797,38 @@ class Ec2Inventory(object): # Skip instances we cannot address (e.g. private VPC subnet) return + # Set the inventory name + hostname = None + if self.hostname_variable: + if self.hostname_variable.startswith('tag_'): + hostname = instance.tags.get(self.hostname_variable[4:], None) + else: + hostname = getattr(instance, self.hostname_variable) + + # If we can't get a nice hostname, use the destination address + if not hostname: + hostname = dest + + hostname = self.to_safe(hostname).lower() + # Add to index - self.index[dest] = [region, instance.id] + self.index[hostname] = [region, instance.id] # Inventory: Group by instance ID (always a group of 1) if self.group_by_instance_id: - self.inventory[instance.id] = [dest] + self.inventory[instance.id] = [hostname] if self.nested_groups: self.push_group(self.inventory, 'instances', instance.id) # Inventory: Group by region if self.group_by_region: - self.push(self.inventory, region, dest) + self.push(self.inventory, region, hostname) if self.nested_groups: self.push_group(self.inventory, 'regions', region) # Inventory: Group by availability zone if self.group_by_availability_zone: - self.push(self.inventory, instance.availability_zone, dest) + self.push(self.inventory, instance.availability_zone, hostname) if self.nested_groups: if self.group_by_region: self.push_group(self.inventory, region, instance.availability_zone) @@ -779,14 +837,14 @@ class Ec2Inventory(object): # Inventory: Group by instance type if self.group_by_instance_type: type_name = self.to_safe('type_' + instance.instance_class) - self.push(self.inventory, type_name, dest) + self.push(self.inventory, type_name, hostname) if self.nested_groups: self.push_group(self.inventory, 'types', type_name) # Inventory: Group by VPC if self.group_by_vpc_id and instance.subnet_group and instance.subnet_group.vpc_id: vpc_id_name = self.to_safe('vpc_id_' + instance.subnet_group.vpc_id) - self.push(self.inventory, vpc_id_name, dest) + self.push(self.inventory, vpc_id_name, hostname) if self.nested_groups: self.push_group(self.inventory, 'vpcs', vpc_id_name) @@ -795,7 +853,7 @@ class Ec2Inventory(object): try: if instance.security_group: key = self.to_safe("security_group_" + instance.security_group.name) - self.push(self.inventory, key, dest) + self.push(self.inventory, key, hostname) if self.nested_groups: self.push_group(self.inventory, 'security_groups', key) @@ -806,20 +864,21 @@ class Ec2Inventory(object): # Inventory: Group by engine if self.group_by_rds_engine: - self.push(self.inventory, self.to_safe("rds_" + instance.engine), dest) + self.push(self.inventory, self.to_safe("rds_" + instance.engine), hostname) if self.nested_groups: self.push_group(self.inventory, 'rds_engines', self.to_safe("rds_" + instance.engine)) # Inventory: Group by parameter group if self.group_by_rds_parameter_group: - self.push(self.inventory, self.to_safe("rds_parameter_group_" + instance.parameter_group.name), dest) + self.push(self.inventory, self.to_safe("rds_parameter_group_" + instance.parameter_group.name), hostname) if self.nested_groups: self.push_group(self.inventory, 'rds_parameter_groups', self.to_safe("rds_parameter_group_" + instance.parameter_group.name)) # Global Tag: all RDS instances - self.push(self.inventory, 'rds', dest) + self.push(self.inventory, 'rds', hostname) - self.inventory["_meta"]["hostvars"][dest] = self.get_host_info_dict_from_instance(instance) + self.inventory["_meta"]["hostvars"][hostname] = self.get_host_info_dict_from_instance(instance) + self.inventory["_meta"]["hostvars"][hostname]['ansible_ssh_host'] = dest def add_elasticache_cluster(self, cluster, region): ''' Adds an ElastiCache cluster to the inventory and index, as long as diff --git a/contrib/inventory/gce.py b/contrib/inventory/gce.py index b13c194a6e7..690d845a02d 100755 --- a/contrib/inventory/gce.py +++ b/contrib/inventory/gce.py @@ -90,6 +90,9 @@ import os import argparse import ConfigParser +import logging +logging.getLogger('libcloud.common.google').addHandler(logging.NullHandler()) + try: import json except ImportError: diff --git a/contrib/inventory/libvirt_lxc.py b/contrib/inventory/libvirt_lxc.py index 1491afd577d..cb34d473cda 100755 --- a/contrib/inventory/libvirt_lxc.py +++ b/contrib/inventory/libvirt_lxc.py @@ -27,11 +27,11 @@ result['all'] = {} pipe = Popen(['virsh', '-q', '-c', 'lxc:///', 'list', '--name', '--all'], stdout=PIPE, universal_newlines=True) result['all']['hosts'] = [x[:-1] for x in pipe.stdout.readlines()] result['all']['vars'] = {} -result['all']['vars']['ansible_connection'] = 'lxc' +result['all']['vars']['ansible_connection'] = 'libvirt_lxc' if len(sys.argv) == 2 and sys.argv[1] == '--list': print(json.dumps(result)) elif len(sys.argv) == 3 and sys.argv[1] == '--host': - print(json.dumps({'ansible_connection': 'lxc'})) + print(json.dumps({'ansible_connection': 'libvirt_lxc'})) else: print("Need an argument, either --list or --host ") diff --git a/contrib/inventory/linode.py b/contrib/inventory/linode.py index f2b61b70756..0aa7098b316 100755 --- a/contrib/inventory/linode.py +++ b/contrib/inventory/linode.py @@ -280,6 +280,11 @@ class LinodeInventory(object): node_vars["datacenter_city"] = self.get_datacenter_city(node) node_vars["public_ip"] = [addr.address for addr in node.ipaddresses if addr.is_public][0] + # Set the SSH host information, so these inventory items can be used if + # their labels aren't FQDNs + node_vars['ansible_ssh_host'] = node_vars["public_ip"] + node_vars['ansible_host'] = node_vars["public_ip"] + private_ips = [addr.address for addr in node.ipaddresses if not addr.is_public] if private_ips: diff --git a/contrib/inventory/openstack.py b/contrib/inventory/openstack.py index 46b43e92212..e8687788505 100755 --- a/contrib/inventory/openstack.py +++ b/contrib/inventory/openstack.py @@ -32,6 +32,13 @@ # all of them and present them as one contiguous inventory. # # See the adjacent openstack.yml file for an example config file +# There are two ansible inventory specific options that can be set in +# the inventory section. +# expand_hostvars controls whether or not the inventory will make extra API +# calls to fill out additional information about each server +# use_hostnames changes the behavior from registering every host with its UUID +# and making a group of its hostname to only doing this if the +# hostname in question has more than one server import argparse import collections @@ -51,7 +58,7 @@ import shade.inventory CONFIG_FILES = ['/etc/ansible/openstack.yaml'] -def get_groups_from_server(server_vars): +def get_groups_from_server(server_vars, namegroup=True): groups = [] region = server_vars['region'] @@ -76,7 +83,8 @@ def get_groups_from_server(server_vars): groups.append(extra_group) groups.append('instance-%s' % server_vars['id']) - groups.append(server_vars['name']) + if namegroup: + groups.append(server_vars['name']) for key in ('flavor', 'image'): if 'name' in server_vars[key]: @@ -94,9 +102,9 @@ def get_groups_from_server(server_vars): return groups -def get_host_groups(inventory): +def get_host_groups(inventory, refresh=False): (cache_file, cache_expiration_time) = get_cache_settings() - if is_cache_stale(cache_file, cache_expiration_time): + if is_cache_stale(cache_file, cache_expiration_time, refresh=refresh): groups = to_json(get_host_groups_from_cloud(inventory)) open(cache_file, 'w').write(groups) else: @@ -104,26 +112,54 @@ def get_host_groups(inventory): return groups +def append_hostvars(hostvars, groups, key, server, namegroup=False): + hostvars[key] = dict( + ansible_ssh_host=server['interface_ip'], + openstack=server) + for group in get_groups_from_server(server, namegroup=namegroup): + groups[group].append(key) + + def get_host_groups_from_cloud(inventory): groups = collections.defaultdict(list) + firstpass = collections.defaultdict(list) hostvars = {} - for server in inventory.list_hosts(): + list_args = {} + if hasattr(inventory, 'extra_config'): + use_hostnames = inventory.extra_config['use_hostnames'] + list_args['expand'] = inventory.extra_config['expand_hostvars'] + else: + use_hostnames = False + + for server in inventory.list_hosts(**list_args): if 'interface_ip' not in server: continue - for group in get_groups_from_server(server): - groups[group].append(server['id']) - hostvars[server['id']] = dict( - ansible_ssh_host=server['interface_ip'], - openstack=server, - ) + firstpass[server['name']].append(server) + for name, servers in firstpass.items(): + if len(servers) == 1 and use_hostnames: + append_hostvars(hostvars, groups, name, servers[0]) + else: + server_ids = set() + # Trap for duplicate results + for server in servers: + server_ids.add(server['id']) + if len(server_ids) == 1 and use_hostnames: + append_hostvars(hostvars, groups, name, servers[0]) + else: + for server in servers: + append_hostvars( + hostvars, groups, server['id'], server, + namegroup=True) groups['_meta'] = {'hostvars': hostvars} return groups -def is_cache_stale(cache_file, cache_expiration_time): +def is_cache_stale(cache_file, cache_expiration_time, refresh=False): ''' Determines if cache file has expired, or if it is still valid ''' - if os.path.isfile(cache_file): + if refresh: + return True + if os.path.isfile(cache_file) and os.path.getsize(cache_file) > 0: mod_time = os.path.getmtime(cache_file) current_time = time.time() if (mod_time + cache_expiration_time) > current_time: @@ -169,14 +205,24 @@ def main(): try: config_files = os_client_config.config.CONFIG_FILES + CONFIG_FILES shade.simple_logging(debug=args.debug) - inventory = shade.inventory.OpenStackInventory( + inventory_args = dict( refresh=args.refresh, config_files=config_files, private=args.private, ) + if hasattr(shade.inventory.OpenStackInventory, 'extra_config'): + inventory_args.update(dict( + config_key='ansible', + config_defaults={ + 'use_hostnames': False, + 'expand_hostvars': True, + } + )) + + inventory = shade.inventory.OpenStackInventory(**inventory_args) if args.list: - output = get_host_groups(inventory) + output = get_host_groups(inventory, refresh=args.refresh) elif args.host: output = to_json(inventory.get_host(args.host)) print(output) diff --git a/contrib/inventory/openstack.yml b/contrib/inventory/openstack.yml index a99bb020580..1520e2937ec 100644 --- a/contrib/inventory/openstack.yml +++ b/contrib/inventory/openstack.yml @@ -26,3 +26,6 @@ clouds: username: stack password: stack project_name: stack +ansible: + use_hostnames: True + expand_hostvars: False diff --git a/contrib/inventory/ovirt.py b/contrib/inventory/ovirt.py index 23646fa2068..f406704ed65 100755 --- a/contrib/inventory/ovirt.py +++ b/contrib/inventory/ovirt.py @@ -172,9 +172,9 @@ class OVirtInventory(object): # If the appropriate environment variables are set, they override # other configuration; process those into our args and kwargs. - kwargs['url'] = os.environ.get('OVIRT_URL') - kwargs['username'] = os.environ.get('OVIRT_EMAIL') - kwargs['password'] = os.environ.get('OVIRT_PASS') + kwargs['url'] = os.environ.get('OVIRT_URL', kwargs['url']) + kwargs['username'] = next(val for val in [os.environ.get('OVIRT_EMAIL'), os.environ.get('OVIRT_USERNAME'), kwargs['username']] if val is not None) + kwargs['password'] = next(val for val in [os.environ.get('OVIRT_PASS'), os.environ.get('OVIRT_PASSWORD'), kwargs['password']] if val is not None) # Retrieve and return the ovirt driver. return API(insecure=True, **kwargs) diff --git a/contrib/inventory/proxmox.py b/contrib/inventory/proxmox.py index ab65c342e4e..c0ffb0b16c6 100755 --- a/contrib/inventory/proxmox.py +++ b/contrib/inventory/proxmox.py @@ -15,6 +15,16 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . +# Updated 2016 by Matt Harris +# +# Added support for Proxmox VE 4.x +# Added support for using the Notes field of a VM to define groups and variables: +# A well-formatted JSON object in the Notes field will be added to the _meta +# section for that VM. In addition, the "groups" key of this JSON object may be +# used to specify group membership: +# +# { "groups": ["utility", "databases"], "a": false, "b": true } + import urllib try: import json @@ -32,29 +42,29 @@ class ProxmoxNodeList(list): def get_names(self): return [node['node'] for node in self] -class ProxmoxQemu(dict): +class ProxmoxVM(dict): def get_variables(self): variables = {} for key, value in iteritems(self): variables['proxmox_' + key] = value return variables -class ProxmoxQemuList(list): +class ProxmoxVMList(list): def __init__(self, data=[]): for item in data: - self.append(ProxmoxQemu(item)) + self.append(ProxmoxVM(item)) def get_names(self): - return [qemu['name'] for qemu in self if qemu['template'] != 1] + return [vm['name'] for vm in self if vm['template'] != 1] def get_by_name(self, name): - results = [qemu for qemu in self if qemu['name'] == name] + results = [vm for vm in self if vm['name'] == name] return results[0] if len(results) > 0 else None def get_variables(self): variables = {} - for qemu in self: - variables[qemu['name']] = qemu.get_variables() + for vm in self: + variables[vm['name']] = vm.get_variables() return variables @@ -105,8 +115,23 @@ class ProxmoxAPI(object): def nodes(self): return ProxmoxNodeList(self.get('api2/json/nodes')) + def vms_by_type(self, node, type): + return ProxmoxVMList(self.get('api2/json/nodes/{}/{}'.format(node, type))) + + def vm_description_by_type(self, node, vm, type): + return self.get('api2/json/nodes/{}/{}/{}/config'.format(node, type, vm)) + def node_qemu(self, node): - return ProxmoxQemuList(self.get('api2/json/nodes/{}/qemu'.format(node))) + return self.vms_by_type(node, 'qemu') + + def node_qemu_description(self, node, vm): + return self.vm_description_by_type(node, vm, 'qemu') + + def node_lxc(self, node): + return self.vms_by_type(node, 'lxc') + + def node_lxc_description(self, node, vm): + return self.vm_description_by_type(node, vm, 'lxc') def pools(self): return ProxmoxPoolList(self.get('api2/json/pools')) @@ -131,6 +156,40 @@ def main_list(options): qemu_list = proxmox_api.node_qemu(node) results['all']['hosts'] += qemu_list.get_names() results['_meta']['hostvars'].update(qemu_list.get_variables()) + lxc_list = proxmox_api.node_lxc(node) + results['all']['hosts'] += lxc_list.get_names() + results['_meta']['hostvars'].update(lxc_list.get_variables()) + + for vm in results['_meta']['hostvars']: + vmid = results['_meta']['hostvars'][vm]['proxmox_vmid'] + try: + type = results['_meta']['hostvars'][vm]['proxmox_type'] + except KeyError: + type = 'qemu' + try: + description = proxmox_api.vm_description_by_type(node, vmid, type)['description'] + except KeyError: + description = None + + try: + metadata = json.loads(description) + except TypeError: + metadata = {} + except ValueError: + metadata = { + 'notes': description + } + + if 'groups' in metadata: + # print metadata + for group in metadata['groups']: + if group not in results: + results[group] = { + 'hosts': [] + } + results[group]['hosts'] += [vm] + + results['_meta']['hostvars'][vm].update(metadata) # pools for pool in proxmox_api.pools().get_names(): diff --git a/contrib/inventory/rackhd.py b/contrib/inventory/rackhd.py new file mode 100755 index 00000000000..92abc4d6a67 --- /dev/null +++ b/contrib/inventory/rackhd.py @@ -0,0 +1,80 @@ +#!/usr/bin/python + +import json +import requests +import os +import argparse +import types + +RACKHD_URL = 'http://localhost:8080' + +class RackhdInventory(object): + def __init__(self, nodeids): + self._inventory = {} + for nodeid in nodeids: + self._load_inventory_data(nodeid) + inventory = {} + for nodeid,info in self._inventory.iteritems(): + inventory[nodeid]= (self._format_output(nodeid, info)) + print(json.dumps(inventory)) + + def _load_inventory_data(self, nodeid): + info = {} + info['ohai'] = RACKHD_URL + '/api/common/nodes/{0}/catalogs/ohai'.format(nodeid ) + info['lookup'] = RACKHD_URL + '/api/common/lookups/?q={0}'.format(nodeid) + + results = {} + for key,url in info.iteritems(): + r = requests.get( url, verify=False) + results[key] = r.text + self._inventory[nodeid] = results + + def _format_output(self, nodeid, info): + try: + node_info = json.loads(info['lookup']) + ipaddress = '' + if len(node_info) > 0: + ipaddress = node_info[0]['ipAddress'] + output = { 'hosts':[ipaddress],'vars':{}} + for key,result in info.iteritems(): + output['vars'][key] = json.loads(result) + output['vars']['ansible_ssh_user'] = 'monorail' + except KeyError: + pass + return output + + +def parse_args(): + parser = argparse.ArgumentParser() + parser.add_argument('--host') + parser.add_argument('--list', action='store_true') + return parser.parse_args() + +try: + #check if rackhd url(ie:10.1.1.45:8080) is specified in the environment + RACKHD_URL = 'http://' + str(os.environ['RACKHD_URL']) +except: + #use default values + pass + +# Use the nodeid specified in the environment to limit the data returned +# or return data for all available nodes +nodeids = [] + +if (parse_args().host): + try: + nodeids += parse_args().host.split(',') + RackhdInventory(nodeids) + except: + pass +if (parse_args().list): + try: + url = RACKHD_URL + '/api/common/nodes' + r = requests.get( url, verify=False) + data = json.loads(r.text) + for entry in data: + if entry['type'] == 'compute': + nodeids.append(entry['id']) + RackhdInventory(nodeids) + except: + pass diff --git a/contrib/inventory/rax.ini b/contrib/inventory/rax.ini index 5a269e16a3a..15948e7b2e6 100644 --- a/contrib/inventory/rax.ini +++ b/contrib/inventory/rax.ini @@ -55,3 +55,12 @@ # will be ignored, and 4 will be used. Accepts a comma separated list, # the first found wins. # access_ip_version = 4 + +# Environment Variable: RAX_CACHE_MAX_AGE +# Default: 600 +# +# A configuration the changes the behavior or the inventory cache. +# Inventory listing performed before this value will be returned from +# the cache instead of making a full request for all inventory. Setting +# this value to 0 will force a full request. +# cache_max_age = 600 \ No newline at end of file diff --git a/contrib/inventory/rax.py b/contrib/inventory/rax.py index 0028f54d201..4ac6b0f47e9 100755 --- a/contrib/inventory/rax.py +++ b/contrib/inventory/rax.py @@ -355,9 +355,12 @@ def get_cache_file_path(regions): def _list(regions, refresh_cache=True): + cache_max_age = int(get_config(p, 'rax', 'cache_max_age', + 'RAX_CACHE_MAX_AGE', 600)) + if (not os.path.exists(get_cache_file_path(regions)) or refresh_cache or - (time() - os.stat(get_cache_file_path(regions))[-1]) > 600): + (time() - os.stat(get_cache_file_path(regions))[-1]) > cache_max_age): # Cache file doesn't exist or older than 10m or refresh cache requested _list_into_cache(regions) diff --git a/contrib/vault/vault-keyring.py b/contrib/vault/vault-keyring.py new file mode 100644 index 00000000000..bc001476c76 --- /dev/null +++ b/contrib/vault/vault-keyring.py @@ -0,0 +1,77 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# (c) 2014, Matt Martz +# +# This file is part of Ansible +# +# Ansible is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Ansible is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Ansible. If not, see . +# +# +# Script to be used with vault_password_file or --vault-password-file +# to retrieve the vault password via your OSes native keyring application +# +# This script requires the ``keyring`` python module +# +# Add a [vault] section to your ansible.cfg file, +# the only option is 'username'. Example: +# +# [vault] +# username = 'ansible_vault' +# +# Additionally, it would be a good idea to configure vault_password_file in +# ansible.cfg +# +# [defaults] +# ... +# vault_password_file = /path/to/vault-keyring.py +# ... +# +# To set your password: python /path/to/vault-keyring.py set +# +# If you choose to not configure the path to vault_password_file in ansible.cfg +# your ansible-playbook command may look like: +# +# ansible-playbook --vault-password-file=/path/to/vault-keyring.py site.yml + +import sys +import getpass +import keyring + +import ansible.constants as C + + +def main(): + parser = C.load_config_file() + try: + username = parser.get('vault', 'username') + except: + sys.stderr.write('No [vault] section configured\n') + sys.exit(1) + + if len(sys.argv) == 2 and sys.argv[1] == 'set': + password = getpass.getpass() + confirm = getpass.getpass('Confirm password: ') + if password == confirm: + keyring.set_password('ansible', username, password) + else: + sys.stderr.write('Passwords do not match\n') + sys.exit(1) + else: + sys.stdout.write('%s\n' % keyring.get_password('ansible', username)) + + sys.exit(0) + + +if __name__ == '__main__': + main() diff --git a/docs/man/man1/ansible-galaxy.1.asciidoc.in b/docs/man/man1/ansible-galaxy.1.asciidoc.in index e6f2d0b4568..9ffe65e45a7 100644 --- a/docs/man/man1/ansible-galaxy.1.asciidoc.in +++ b/docs/man/man1/ansible-galaxy.1.asciidoc.in @@ -12,7 +12,7 @@ ansible-galaxy - manage roles using galaxy.ansible.com SYNOPSIS -------- -ansible-galaxy [init|info|install|list|remove] [--help] [options] ... +ansible-galaxy [delete|import|info|init|install|list|login|remove|search|setup] [--help] [options] ... DESCRIPTION @@ -20,7 +20,7 @@ DESCRIPTION *Ansible Galaxy* is a shared repository for Ansible roles. The ansible-galaxy command can be used to manage these roles, -or by creating a skeleton framework for roles you'd like to upload to Galaxy. +or for creating a skeleton framework for roles you'd like to upload to Galaxy. COMMON OPTIONS -------------- @@ -29,7 +29,6 @@ COMMON OPTIONS Show a help message related to the given sub-command. - INSTALL ------- @@ -145,6 +144,204 @@ The path to the directory containing your roles. The default is the *roles_path* configured in your *ansible.cfg* file (/etc/ansible/roles if not configured) +SEARCH +------ + +The *search* sub-command returns a filtered list of roles found on the remote +server. + + +USAGE +~~~~~ + +$ ansible-galaxy search [options] [searchterm1 searchterm2] + + +OPTIONS +~~~~~~~ +*--galaxy-tags*:: + +Provide a comma separated list of Galaxy Tags on which to filter. + +*--platforms*:: + +Provide a comma separated list of Platforms on which to filter. + +*--author*:: + +Specify the username of a Galaxy contributor on which to filter. + +*-c*, *--ignore-certs*:: + +Ignore TLS certificate errors. + +*-s*, *--server*:: + +Override the default server https://galaxy.ansible.com. + + +INFO +---- + +The *info* sub-command shows detailed information for a specific role. +Details returned about the role included information from the local copy +as well as information from galaxy.ansible.com. + +USAGE +~~~~~ + +$ ansible-galaxy info [options] role_name[, version] + +OPTIONS +~~~~~~~ + +*-p* 'ROLES_PATH', *--roles-path=*'ROLES_PATH':: + +The path to the directory containing your roles. The default is the *roles_path* +configured in your *ansible.cfg* file (/etc/ansible/roles if not configured) + +*-c*, *--ignore-certs*:: + +Ignore TLS certificate errors. + +*-s*, *--server*:: + +Override the default server https://galaxy.ansible.com. + + +LOGIN +----- + +The *login* sub-command is used to authenticate with galaxy.ansible.com. +Authentication is required to use the import, delete and setup commands. +It will authenticate the user, retrieve a token from Galaxy, and store it +in the user's home directory. + +USAGE +~~~~~ + +$ ansible-galaxy login [options] + +The *login* sub-command prompts for a *GitHub* username and password. It does +NOT send your password to Galaxy. It actually authenticates with GitHub and +creates a personal access token. It then sends the personal access token to +Galaxy, which in turn verifies that you are you and returns a Galaxy access +token. After authentication completes the *GitHub* personal access token is +destroyed. + +If you do not wish to use your GitHub password, or if you have two-factor +authentication enabled with GitHub, use the *--github-token* option to pass a +personal access token that you create. Log into GitHub, go to Settings and +click on Personal Access Token to create a token. + +OPTIONS +~~~~~~~ + +*-c*, *--ignore-certs*:: + +Ignore TLS certificate errors. + +*-s*, *--server*:: + +Override the default server https://galaxy.ansible.com. + +*--github-token*:: + +Authenticate using a *GitHub* personal access token rather than a password. + + +IMPORT +------ + +Import a role from *GitHub* to galaxy.ansible.com. Requires the user first +authenticate with galaxy.ansible.com using the *login* subcommand. + +USAGE +~~~~~ + +$ ansible-galaxy import [options] github_user github_repo + +OPTIONS +~~~~~~~ +*-c*, *--ignore-certs*:: + +Ignore TLS certificate errors. + +*-s*, *--server*:: + +Override the default server https://galaxy.ansible.com. + +*--branch*:: + +Provide a specific branch to import. When a branch is not specified the +branch found in meta/main.yml is used. If no branch is specified in +meta/main.yml, the repo's default branch (usually master) is used. + + +DELETE +------ + +The *delete* sub-command will delete a role from galaxy.ansible.com. Requires +the user first authenticate with galaxy.ansible.com using the *login* subcommand. + +USAGE +~~~~~ + +$ ansible-galaxy delete [options] github_user github_repo + +OPTIONS +~~~~~~~ + +*-c*, *--ignore-certs*:: + +Ignore TLS certificate errors. + +*-s*, *--server*:: + +Override the default server https://galaxy.ansible.com. + + +SETUP +----- + +The *setup* sub-command creates an integration point for *Travis CI*, enabling +galaxy.ansible.com to receive notifications from *Travis* on build completion. +Requires the user first authenticate with galaxy.ansible.com using the *login* +subcommand. + +USAGE +~~~~~ + +$ ansible-galaxy setup [options] source github_user github_repo secret + +* Use *travis* as the source value. In the future additional source values may + be added. + +* Provide your *Travis* user token as the secret. The token is not stored by + galaxy.ansible.com. A hash is created using github_user, github_repo + and your token. The hash value is what actually gets stored. + +OPTIONS +~~~~~~~ + +*-c*, *--ignore-certs*:: + +Ignore TLS certificate errors. + +*-s*, *--server*:: + +Override the default server https://galaxy.ansible.com. + +--list:: + +Show your configured integrations. Provids the ID of each integration +which can be used with the remove option. + +--remove:: + +Remove a specific integration. Provide the ID of the integration to +be removed. + AUTHOR ------ diff --git a/docs/man/man1/ansible-playbook.1.asciidoc.in b/docs/man/man1/ansible-playbook.1.asciidoc.in index 5686162f212..47e68d31418 100644 --- a/docs/man/man1/ansible-playbook.1.asciidoc.in +++ b/docs/man/man1/ansible-playbook.1.asciidoc.in @@ -34,7 +34,12 @@ The names of one or more YAML format files to run as ansible playbooks. OPTIONS ------- -*--ask-become-pass*:: +*-b*, *--become*:: + +Use privilege escalation (specific one depends on become_method), +this does not imply prompting for passwords. + +*-K*, *--ask-become-pass*:: Ask for privilege escalation password. @@ -47,7 +52,7 @@ For example, using ssh and not having a key-based authentication with ssh-agent Prompt for su password, used with --su (deprecated, use become). -*-K*, *--ask-sudo-pass*:: +*--ask-sudo-pass*:: Prompt for the password to use with --sudo, if any (deprecated, use become). @@ -96,12 +101,12 @@ Show help page and exit *-i* 'PATH', *--inventory=*'PATH':: The 'PATH' to the inventory, which defaults to '/etc/ansible/hosts'. -Alternatively you can use a comma separated list of hosts or single host with traling comma 'host,'. +Alternatively, you can use a comma-separated list of hosts or a single host with a trailing comma 'host,'. *-l* 'SUBSET', *--limit=*'SUBSET':: Further limits the selected host/group patterns. -You can prefix it with '~' to indicate that the pattern in a regex. +You can prefix it with '~' to indicate that the pattern is a regex. *--list-hosts*:: @@ -125,10 +130,6 @@ environment variable. Use this file to authenticate the connection -*--skip-tages=*'SKIP_TAGS':: - -Only run plays and tasks whose tags do not match these values. - *--start-at-task=*'START_AT':: Start the playbook at the task matching this name. @@ -169,7 +170,7 @@ Add the specified arguments to any ssh command-line. *-U* 'SUDO_USERNAME', *--sudo-user=*'SUDO_USERNAME':: -Sudo to 'SUDO_USERNAME' deafult is root. (deprecated, use become). +Sudo to 'SUDO_USERNAME' default is root. (deprecated, use become). *--skip-tags=*'SKIP_TAGS':: @@ -204,6 +205,24 @@ up to three times for more output. Show program's version number and exit. +EXIT STATUS +----------- + +*0* -- OK or no hosts matched + +*1* -- Error + +*2* -- One or more hosts failed + +*3* -- One or more hosts were unreachable + +*4* -- Parser error + +*5* -- Bad or incomplete options + +*99* -- User interrupted execution + +*250* -- Unexpected error ENVIRONMENT ----------- diff --git a/docs/man/man1/ansible-pull.1.asciidoc.in b/docs/man/man1/ansible-pull.1.asciidoc.in index 333b8e34e0f..9f4e1993f31 100644 --- a/docs/man/man1/ansible-pull.1.asciidoc.in +++ b/docs/man/man1/ansible-pull.1.asciidoc.in @@ -54,7 +54,12 @@ OPTIONS Adds the hostkey for the repo URL if not already added. -*--ask-become-pass*:: +*-b*, *--become*:: + +Use privilege escalation (specific one depends on become_method), +this does not imply prompting for passwords. + +*-K*, *--ask-become-pass*:: Ask for privilege escalation password. @@ -67,7 +72,7 @@ For example, using ssh and not having a key-based authentication with ssh-agent Prompt for su password, used with --su (deprecated, use become). -*-K*, *--ask-sudo-pass*:: +*--ask-sudo-pass*:: Prompt for the password to use with --sudo, if any (deprecated, use become). @@ -95,6 +100,10 @@ Force running of playbook even if unable to update playbook repository. This can be useful, for example, to enforce run-time state when a network connection may not always be up or possible. +*--full*:: + +Do a full clone of the repository. By default ansible-pull will do a shallow clone based on the last revision. + *-h*, *--help*:: Show the help message and exit. diff --git a/docs/man/man1/ansible.1.asciidoc.in b/docs/man/man1/ansible.1.asciidoc.in index 4cabe6c1dce..92b7e826bb5 100644 --- a/docs/man/man1/ansible.1.asciidoc.in +++ b/docs/man/man1/ansible.1.asciidoc.in @@ -37,7 +37,12 @@ OPTIONS The 'ARGUMENTS' to pass to the module. -*--ask-become-pass*:: +*-b*, *--become*:: + +Use privilege escalation (specific one depends on become_method), +this does not imply prompting for passwords. + +*K*, *--ask-become-pass*:: Ask for privilege escalation password. @@ -50,7 +55,7 @@ For example, using ssh and not having a key-based authentication with ssh-agent Prompt for su password, used with --su (deprecated, use become). -*-K*, *--ask-sudo-pass*:: +*--ask-sudo-pass*:: Prompt for the password to use with --sudo, if any (deprecated, use become). @@ -104,7 +109,7 @@ Alternatively you can use a comma separated list of hosts or single host with tr *-l* 'SUBSET', *--limit=*'SUBSET':: Further limits the selected host/group patterns. -You can prefix it with '~' to indicate that the patter in a regex. +You can prefix it with '~' to indicate that the pattern is a regex. *--list-hosts*:: diff --git a/docs/proposals/auto-install-roles.md b/docs/proposals/auto-install-roles.md new file mode 100644 index 00000000000..9fb17fc2b1e --- /dev/null +++ b/docs/proposals/auto-install-roles.md @@ -0,0 +1,150 @@ +# Auto Install Ansible roles + +*Author*: Will Thames <@willthames> + +*Date*: 19/02/2016 + +## Motivation + +To use the latest (or even a specific) version of a playbook with the +appropriate roles, the following steps are typically required: + +``` +git pull upstream branch +ansible-galaxy install -r path/to/rolesfile.yml -p path/to/rolesdir -f +ansible-playbook run-the-playbook.yml +``` + +### Problems + +- The most likely step in this process to be forgotten is the middle step. While we can improve processes and documentation to try and ensure that this step is not skipped, we can improve ansible-playbook so that the step is not required. +- Ansible-galaxy does ot sufficiently handle versioning. +- There is not a consistent format for specifying a role in a playbook or a dependent role in meta/main.yml. + +## Approaches + +### Approach 1: Specify rolesfile and rolesdir in playbook + +Provide new `rolesdir` and `rolesfile` keywords: + +``` +- hosts: application-env + become: True + rolesfile: path/to/rolesfile.yml + rolesdir: path/to/rolesdir + roles: + - roleA + - { role: roleB, tags: role_roleB } +``` + +Running ansible-playbook against such a playbook would cause the roles listed in +`rolesfile` to be installed in `rolesdir`. + +Add new configuration to allow default rolesfile, default rolesdir and +whether or not to auto update roles (defaulting to False) + +#### Advantages + +- Existing mechanism for roles management is maintained +- Playbooks are not polluted with roles 'meta' information (version, source) + +#### Disadvantage + +- Adds two new keywords +- Adds three new configuration variables for defaults + +### Approach 2: Allow rolesfile inclusion + +Allow the `roles` section to include a roles file: + +``` +- hosts: application-env + become: True + roles: + - include: path/to/rolesfile.yml +``` + +Running this playbook would cause the roles to be updated from the included +roles file. + +This would also be functionally equivalent to specifying the roles file +content within the playbook: + +``` +- hosts: application-env + become: True + roles: + - src: https://git.example.com/roleA.git + scm: git + version: 0.1 + - src: https://git.example.com/roleB.git + scm: git + version: 0.3 + tags: role_roleB +``` + +#### Advantages + +- The existing rolesfile mechanism is maintained +- Uses familiar inclusion mechanism + +#### Disadvantage + +- Separate playbooks would need separate rolesfiles. For example, a provision + playbook and upgrade playbook would likely have some overlap - currently + you can use the same rolesfile with ansible-galaxy so that the same + roles are available but only a subset of roles is used by the smaller + playbook. +- The roles file would need to be able to include playbook features such + as role tagging. +- New configuration defaults would likely still be required (and possibly + an override keyword for rolesdir and role auto update) + + +### Approach 3: + +*Author*: chouseknecht<@chouseknecht> + +*Date*: 24/02/2016 + +This is a combination of ideas taken from IRC, the ansible development group, and conversations at the recent contributor's summit. It also incorporates most of the ideas from Approach 1 (above) with two notable texceptions: 1) it elmintates maintaing a roles file (or what we think of today as requirements.yml); and 2) it does not include the definition of rolesdir in the playbook. + +Here's the approach: + +- Share the role install logic between ansible-playbook and ansible-galaxy so that ansible-playbook can resolve and install missing roles at playbook run time simply by evaluating the playbook. +- Ansible-galaxy installs or preloads roles also by examining a playbook. +- Deprecate support for requirements.yaml (the two points above make it unnecessary). +- Make ansible-playbook auto-downloading of roles configurable in ansible.cfg. In certain circumstance it may be desirable to disable auto-download. +- Provide one format for specifying a role whether in a playbook or in meta/main.yml. Suggested format: + + ``` + { + 'scm': 'git', + 'src': 'http://git.example.com/repos/repo.git', + 'version': 'v1.0', + 'name': 'repo’ + } + ``` +- For roles installed from Galaxy, Galaxy should provide some measure of security against version change. Galaxy should track the commit related to a version. If the role owner changes historical versions (today tags) and thus changes the commit hash, the affected version would become un-installable. + +- Refactor the install process to encompass the following : + + - Idempotency - If a role version is already installed, don’t attempt to install it again. If symlinks are present (see below), don’t break or remove them. + - Provide a --force option that overrides idempotency. + - Install roles via tree-ish references, not just tags or commits (PR exists for this). + - Support a whitelist of role sources. Galaxy should not be automatically assumed to be part of the whitelist. + - Continue to be recursive, allowing roles to have dependencies specified in meta/main.yml. + - Continue to install roles in the roles_path. + - Use a symlink approach to managing role versions in the roles_path. Example: + + ``` + roles/ + briancoca.oracle_java7.v1.0 + briancoca.oracle_java7.v2.2 + briancoca.oracle_java7.qs3ih6x + briancoca.oracle_java7 => briancoca.oracle_java7.qs3ih6x + ``` + +## Conclusion + +Feedback is requested to improve any of the above approaches, or provide further approaches to solve this problem. diff --git a/docs/proposals/docker/docker_container_module.md b/docs/proposals/docker/docker_container_module.md new file mode 100644 index 00000000000..886b510482b --- /dev/null +++ b/docs/proposals/docker/docker_container_module.md @@ -0,0 +1,487 @@ +# Docker_Container Module Proposal + +## Purpose and Scope: + +The purpose of docker_container is to manage the lifecycle of a container. The module will provide a mechanism for +moving the container between absent, present, stopped and started states. It will focus purely on managing container +state. The intention of the narrow focus is to make understanding and using the module clear and keep maintenance +and testing as easy as possible. + +Docker_container will manage a container using docker-py to communicate with either a local or remote API. It will +support API versions >= 1.14. API connection details will be handled externally in a shared utility module similar to +how other cloud modules operate. + +The container world is moving rapidly, so the goal is to create a suite of docker modules that keep pace, with docker_container +leading the way. If this project is successful, it will naturally deprecate the existing docker module. + +## Parameters: + +Docker_container will accept the parameters listed below. An attempt has been made to represent all the options available to +docker's create, kill, pause, run, rm, start, stop and update commands. + +Parameters for connecting to the API are not listed here. They are included in the common utility module mentioned above. + +``` +blkio_weight: + description: + - Block IO (relative weight), between 10 and 1000. + default: null + +capabilities: + description: + - List of capabilities to add to the container. + default: null + +command: + description: + - Command or list of commands to execute in the container when it starts. + default: null + +cpu_period: + description: + - Limit CPU CFS (Completely Fair Scheduler) period + default: 0 + +cpu_quota: + description: + - Limit CPU CFS (Completely Fair Scheduler) quota + default: 0 + +cpuset_cpus: + description: + - CPUs in which to allow execution C(1,3) or C(1-3). + default: null + +cpuset_mems: + description: + - Memory nodes (MEMs) in which to allow execution C(0-3) or C(0,1) + default: null + +cpu_shares: + description: + - CPU shares (relative weight). + default: null + +detach: + description: + - Enable detached mode to leave the container running in background. + If disabled, fail unless the process exits cleanly. + default: true + +devices: + description: + - List of host device bindings to add to the container. Each binding is a mapping expressed + in the format: :: + default: null + +dns_servers: + description: + - List of custom DNS servers. + default: null + +dns_search_domains: + description: + - List of custom DNS search domains. + default: null + +env: + description: + - Dictionary of key,value pairs. + default: null + +entrypoint: + description: + - String or list of commands that overwrite the default ENTRYPOINT of the image. + default: null + +etc_hosts: + description: + - Dict of host-to-IP mappings, where each host name is key in the dictionary. Hostname will be added to the + container's /etc/hosts file. + default: null + +exposed_ports: + description: + - List of additional container ports to expose for port mappings or links. + If the port is already exposed using EXPOSE in a Dockerfile, it does not + need to be exposed again. + default: null + aliases: + - exposed + +force_kill: + description: + - Use with absent, present, started and stopped states to use the kill command rather + than the stop command. + default: false + +groups: + description: + - List of additional group names and/or IDs that the container process will run as. + default: null + +hostname: + description: + - Container hostname. + default: null + +image: + description: + - Container image used to create and match containers. + required: true + +interactive: + description: + - Keep stdin open after a container is launched, even if not attached. + default: false + +ipc_mode: + description: + - Set the IPC mode for the container. Can be one of + 'container:' to reuse another container's IPC namespace + or 'host' to use the host's IPC namespace within the container. + default: null + +keep_volumes: + description: + - Retain volumes associated with a removed container. + default: false + +kill_signal: + description: + - Override default signal used to kill a running container. + default null: + +kernel_memory: + description: + - Kernel memory limit (format: []). Number is a positive integer. + Unit can be one of b, k, m, or g. Minimum is 4M. + default: 0 + +labels: + description: + - Dictionary of key value pairs. + default: null + +links: + description: + - List of name aliases for linked containers in the format C(container_name:alias) + default: null + +log_driver: + description: + - Specify the logging driver. + choices: + - json-file + - syslog + - journald + - gelf + - fluentd + - awslogs + - splunk + defult: json-file + +log_options: + description: + - Dictionary of options specific to the chosen log_driver. See https://docs.docker.com/engine/admin/logging/overview/ + for details. + required: false + default: null + +mac_address: + description: + - Container MAC address (e.g. 92:d0:c6:0a:29:33) +default: null + +memory: + description: + - Memory limit (format: []). Number is a positive integer. + Unit can be one of b, k, m, or g + default: 0 + +memory_reservation: + description: + - Memory soft limit (format: []). Number is a positive integer. + Unit can be one of b, k, m, or g + default: 0 + +memory_swap: + description: + - Total memory limit (memory + swap, format:[]). + Number is a positive integer. Unit can be one of b, k, m, or g. + default: 0 + +memory_swappiness: + description: + - Tune a container's memory swappiness behavior. Accepts an integer between 0 and 100. + default: 0 + +name: + description: + - Assign a name to a new container or match an existing container. + - When identifying an existing container name may be a name or a long or short container ID. + required: true + +network_mode: + description: + - Connect the container to a network. + choices: + - bridge + - container: + - host + - none + default: null + +networks: + description: + - Dictionary of networks to which the container will be connected. The dictionary must have a name key (the name of the network). + Optional keys include: aliases (a list of container aliases), and links (a list of links in the format C(container_name:alias)). + default: null + +oom_killer: + desription: + - Whether or not to disable OOM Killer for the container. + default: false + +paused: + description: + - Use with the started state to pause running processes inside the container. + default: false + +pid_mode: + description: + - Set the PID namespace mode for the container. Currenly only supports 'host'. + default: null + +privileged: + description: + - Give extended privileges to the container. + default: false + +published_ports: + description: + - List of ports to publish from the container to the host. + - Use docker CLI syntax: C(8000), C(9000:8000), or C(0.0.0.0:9000:8000), where 8000 is a + container port, 9000 is a host port, and 0.0.0.0 is a host interface. + - Container ports must be exposed either in the Dockerfile or via the C(expose) option. + - A value of ALL will publish all exposed container ports to random host ports, ignoring + any other mappings. + aliases: + - ports + +read_only: + description: + - Mount the container's root file system as read-only. + default: false + +recreate: + description: + - Use with present and started states to force the re-creation of an existing container. + default: false + +restart: + description: + - Use with started state to force a matching container to be stopped and restarted. + default: false + +restart_policy: + description: + - Container restart policy. + choices: + - on-failure + - always + default: on-failure + +restart_retries: + description: + - Use with restart policy to control maximum number of restart attempts. + default: 0 + +shm_size: + description: + - Size of `/dev/shm`. The format is ``. `number` must be greater than `0`. + Unit is optional and can be `b` (bytes), `k` (kilobytes), `m` (megabytes), or `g` (gigabytes). + - Ommitting the unit defaults to bytes. If you omit the size entirely, the system uses `64m`. + default: null + +security_opts: + description: + - List of security options in the form of C("label:user:User") + default: null + +state: + description: + - "absent" - A container matching the specified name will be stopped and removed. Use force_kill to kill the container + rather than stopping it. Use keep_volumes to retain volumes associated with the removed container. + + - "present" - Asserts the existence of a container matching the name and any provided configuration parameters. If no + container matches the name, a container will be created. If a container matches the name but the provided configuration + does not match, the container will be updated, if it can be. If it cannot be updated, it will be removed and re-created + with the requested config. Use recreate to force the re-creation of the matching container. Use force_kill to kill the + container rather than stopping it. Use keep_volumes to retain volumes associated with a removed container. + + - "started" - Asserts there is a running container matching the name and any provided configuration. If no container + matches the name, a container will be created and started. If a container matching the name is found but the + configuration does not match, the container will be updated, if it can be. If it cannot be updated, it will be removed + and a new container will be created with the requested configuration and started. Use recreate to always re-create a + matching container, even if it is running. Use restart to force a matching container to be stopped and restarted. Use + force_kill to kill a container rather than stopping it. Use keep_volumes to retain volumes associated with a removed + container. + + - "stopped" - a container matching the specified name will be stopped. Use force_kill to kill a container rather than + stopping it. + + required: false + default: started + choices: + - absent + - present + - stopped + - started + +stop_signal: + description: + - Override default signal used to stop the container. + default: null + +stop_timeout: + description: + - Number of seconds to wait for the container to stop before sending SIGKILL. + required: false + +trust_image_content: + description: + - If true, skip image verification. + default: false + +tty: + description: + - Allocate a psuedo-TTY. + default: false + +ulimits: + description: + - List of ulimit options. A ulimit is specified as C(nofile:262144:262144) + default: null + +user: + description + - Sets the username or UID used and optionally the groupname or GID for the specified command. + - Can be [ user | user:group | uid | uid:gid | user:gid | uid:group ] + default: null + +uts: + description: + - Set the UTS namespace mode for the container. + default: null + +volumes: + description: + - List of volumes to mount within the container. + - 'Use docker CLI-style syntax: C(/host:/container[:mode])' + - You can specify a read mode for the mount with either C(ro) or C(rw). + - SELinux hosts can additionally use C(z) or C(Z) to use a shared or + private label for the volume. +default: null + +volume_driver: + description: + - The container's volume driver. + default: none + +volumes_from: + description: + - List of container names or Ids to get volumes from. + default: null +``` + + +## Examples: + +``` +- name: Create a data container + docker_container: + name: mydata + image: busybox + volumes: + - /data + +- name: Re-create a redis container + docker_container: + name: myredis + image: redis + command: redis-server --appendonly yes + state: present + recreate: yes + expose: + - 6379 + volumes_from: + - mydata + +- name: Restart a container + docker_container: + name: myapplication + image: someuser/appimage + state: started + restart: yes + links: + - "myredis:aliasedredis" + devices: + - "/dev/sda:/dev/xvda:rwm" + ports: + - "8080:9000" + - "127.0.0.1:8081:9001/udp" + env: + SECRET_KEY: ssssh + + +- name: Container present + docker_container: + name: mycontainer + state: present + recreate: yes + forcekill: yes + image: someplace/image + command: echo "I'm here!" + + +- name: Start 4 load-balanced containers + docker_container: + name: "container{{ item }}" + state: started + recreate: yes + image: someuser/anotherappimage + command: sleep 1d + with_sequence: count=4 + +-name: remove container + docker_container: + name: ohno + state: absent + +- name: Syslogging output + docker_container: + name: myservice + state: started + log_driver: syslog + log_opt: + syslog-address: tcp://my-syslog-server:514 + syslog-facility: daemon + syslog-tag: myservice + +``` + +## Returns: + +The JSON object returned by the module will include a *results* object providing `docker inspect` output for the affected container. + +``` +{ + changed: True, + failed: False, + rc: 0 + results: { + < the results of `docker inspect` > + } +} +``` diff --git a/docs/proposals/docker/docker_files_module.md b/docs/proposals/docker/docker_files_module.md new file mode 100644 index 00000000000..3970584f0d3 --- /dev/null +++ b/docs/proposals/docker/docker_files_module.md @@ -0,0 +1,159 @@ +# Docker_Files Modules Proposal + +## Purpose and Scope + +The purpose of docker_files is to provide for retrieving a file or folder from a container's file system, +inserting a file or folder into a container, exporting a container's entire filesystem as a tar archive, or +retrieving a list of changed files from a container's file system. + +Docker_files will manage a container using docker-py to communicate with either a local or remote API. It will +support API versions >= 1.14. API connection details will be handled externally in a shared utility module similar to +how other cloud modules operate. + +## Parameters + +Docker_files accepts the parameters listed below. API connection parameters will be part of a shared utility module +as mentioned above. + +``` +diff: + description: + - Provide a list of container names or IDs. For each container a list of changed files and directories found on the + container's file system will be returned. Diff is mutually exclusive from all other options except event_type. + Use event_type to choose which events to include in the output. + default: null + +export: + description: + - Provide a container name or ID. The container's file system will be exported to a tar archive. Use dest + to provide a path for the archive on the local file system. If the output file already exists, it will not be + overwritten. Use the force option to overwrite an existing archive. + default: null + +dest: + description: + - Destination path of copied files. If the destination is a container file system, precede the path with a + container name or ID + ':'. For example, C(mycontainer:/path/to/file.txt). If the destination path does not + exist, it will be created. If the destination path exists on a the local filesystem, it will not be overwritten. + Use the force option to overwrite existing files on the local filesystem. + default: null + +force: + description: + - Overwrite existing files on the local filesystem. + default: false + +follow_link: + description: + - Follow symbolic links in the src path. If src is local and file is a symbolic link, the symbolic link, not the + target is copied by default. To copy the link target and not the link, set follow_link to true. + default: false + +event_type: + description: + - Select the specific event type to list in the diff output. + choices: + - all + - add + - delete + - change + default: all + +src: + description: + - The source path of file(s) to be copied. If source files are found on the container's file system, precede the + path with the container name or ID + ':'. For example, C(mycontainer:/path/to/files). + default: null + +``` + +## Examples + +``` +- name: Copy files from the local file system to a container's file system + docker_files: + src: /tmp/rpm + dest: mycontainer:/tmp + follow_links: yes + +- name: Copy files from the container to the local filesystem and overwrite existing files + docker_files: + src: container1:/var/lib/data + dest: /tmp/container1/data + force: yes + +- name: Export container filesystem + docker_file: + export: container1 + dest: /tmp/conainer1.tar + force: yes + +- name: List all differences for multiple containers. + docker_files: + diff: + - mycontainer1 + - mycontainer2 + +- name: Included changed files only in diff output + docker_files: + diff: + - mycontainer1 + event_type: change +``` + +## Returns + +Returned from diff: + +``` +{ + changed: false, + failed: false, + rc: 0, + results: { + mycontainer1: [ + { state: 'C', path: '/dev' }, + { state: 'A', path: '/dev/kmsg' }, + { state: 'C', path: '/etc' }, + { state: 'A', path: '/etc/mtab' } + ], + mycontainer2: [ + { state: 'C', path: '/foo' }, + { state: 'A', path: '/foo/bar.txt' } + ] + } +} +``` + +Returned when copying files: + +``` +{ + changed: true, + failed: false, + rc: 0, + results: { + src: /tmp/rpms, + dest: mycontainer:/tmp + files_copied: [ + 'file1.txt', + 'file2.jpg' + ] + } +} +``` + +Return when exporting container filesystem: + +``` +{ + changed: true, + failed: false, + rc: 0, + results: { + src: container_name, + dest: local/path/archive_name.tar + } +} + +``` diff --git a/docs/proposals/docker/docker_image_facts_module.md b/docs/proposals/docker/docker_image_facts_module.md new file mode 100644 index 00000000000..a399e682b01 --- /dev/null +++ b/docs/proposals/docker/docker_image_facts_module.md @@ -0,0 +1,47 @@ + +# Docker_Image_Facts Module Proposal + +## Purpose and Scope + +The purpose of docker_image_facts is to inspect docker images. + +Docker_image_facts will use docker-py to communicate with either a local or remote API. It will +support API versions >= 1.14. API connection details will be handled externally in a shared utility module similar +to how other cloud modules operate. + +## Parameters + +Docker_image_facts will support the parameters listed below. API connection parameters will be part of a shared +utility module as mentioned above. + +``` +name: + description: + - An image name or list of image names. The image name can include a tag using the format C(name:tag). + default: null +``` + +## Examples + +``` +- name: Inspect all images + docker_image_facts + register: image_facts + +- name: Inspect a single image + docker_image_facts: + name: myimage:v1 + register: myimage_v1_facts +``` + +## Returns + +``` +{ + changed: False + failed: False + rc: 0 + result: [ < inspection output > ] +} +``` + diff --git a/docs/proposals/docker/docker_image_module.md b/docs/proposals/docker/docker_image_module.md new file mode 100644 index 00000000000..9284ca96692 --- /dev/null +++ b/docs/proposals/docker/docker_image_module.md @@ -0,0 +1,207 @@ + +# Docker_Image Module Proposal + +## Purpose and Scope + +The purpose is to update the existing docker_image module. The updates include expanding the module's capabilities to +match the build, load, pull, push, rmi, and save docker commands and adding support for remote registries. + +Docker_image will manage images using docker-py to communicate with either a local or remote API. It will +support API versions >= 1.14. API connection details will be handled externally in a shared utility module similar +to how other cloud modules operate. + +## Parameters + +Docker_image will support the parameters listed below. API connection parameters will be part of a shared utility +module as mentioned above. + +``` +archive_path: + description: + - Save image to the provided path. Use with state present to always save the image to a tar archive. If + intermediate directories in the path do not exist, they will be created. If a matching + archive already exists, it will be overwritten. + default: null + +config_path: + description: + - Path to a custom docker config file. Docker-py defaults to using ~/.docker/config.json. + +cgroup_parent: + description: + - Optional parent cgroup for build containers. + default: null + +cpu_shares: + description: + - CPU shares for build containers. Integer value. + default: 0 + +cpuset_cpus: + description: + - CPUs in which to allow build container execution C(1,3) or C(1-3). + default: null + +dockerfile: + description: + - Name of dockerfile to use when building an image. + default: Dockerfile + +email: + description: + - The email for the registry account. Provide with username and password when credentials are not encoded + in docker configuration file or when encoded credentials should be updated. + default: null + nolog: true + +force: + description: + - Use with absent state to un-tag and remove all images matching the specified name. Use with present state to + force a pull or rebuild of the image. + default: false + +load_path: + description: + - Use with state present to load a previously save image. Provide the full path to the image archive file. + default: null + +memory: + description: + - Build container limit. Memory limit specified as a positive integer for number of bytes. + +memswap: + description: + - Build container limit. Total memory (memory + swap). Specify as a positive integer for number of bytes or + -1 to disable swap. + default: null + +name: + description: + - Image name or ID. + required: true + +nocache: + description: + - Do not use cache when building an image. + deafult: false + +password: + description: + - Password used when connecting to the registry. Provide with username and email when credentials are not encoded + in docker configuration file or when encoded credentials should be updated. + default: null + nolog: true + +path: + description: + - Path to Dockerfile and context from which to build an image. + default: null + +push: + description: + - Use with state present to always push an image to the registry. + default: false + +registry: + description: + - URL of the registry. If not provided, defaults to Docker Hub. + default: null + +rm: + description: + - Remove intermediate containers after build. + default: true + +tag: + description: + - Image tags. When pulling or pushing, set to 'all' to include all tags. + default: latest + +url: + description: + - The location of a Git repository. The repository acts as the context when building an image. + - Mutually exclusive with path. + +username: + description: + - Username used when connecting to the registry. Provide with password and email when credentials are not encoded + in docker configuration file or when encoded credentials should be updated. + default: null + nolog: true + +state: + description: + - "absent" - if image exists, unconditionally remove it. Use the force option to un-tag and remove all images + matching the provided name. + - "present" - check if image is present with the provided tag. If the image is not present or the force option + is used, the image will either be pulled from the registry, built or loaded from an archive. To build the image, + provide a path or url to the context and Dockerfile. To load an image, use load_path to provide a path to + an archive file. If no path, url or load_path is provided, the image will be pulled. Use the registry + parameters to control the registry from which the image is pulled. + +required: false +default: present +choices: + - absent + - present + +http_timeout: + description: + - Timeout for HTTP requests during the image build operation. Provide a positive integer value for the number of + seconds. + default: null + +``` + + +## Examples + +``` +- name: build image + docker_image: + path: "/path/to/build/dir" + name: "my_app" + tags: + - v1.0 + - mybuild + +- name: force pull an image and all tags + docker_image: + name: "my/app" + force: yes + tags: all + +- name: untag and remove image + docker_image: + name: "my/app" + state: absent + force: yes + +- name: push an image to Docker Hub with all tags + docker_image: + name: my_image + push: yes + tags: all + +- name: pull image from a private registry + docker_image: + name: centos + registry: https://private_registry:8080 + +``` + + +## Returns + +``` +{ + changed: True + failed: False + rc: 0 + action: built | pulled | loaded | removed | none + msg: < text confirming the action that was taken > + results: { + < output from docker inspect for the affected image > + } +} +``` \ No newline at end of file diff --git a/docs/proposals/docker/docker_network_facts.md b/docs/proposals/docker/docker_network_facts.md new file mode 100644 index 00000000000..84576049ba1 --- /dev/null +++ b/docs/proposals/docker/docker_network_facts.md @@ -0,0 +1,48 @@ + +# Docker_Network_Facts Module Proposal + +## Purpose and Scope + +Docker_network_facts will inspect networks. + +Docker_network_facts will use docker-py to communicate with either a local or remote API. It will +support API versions >= 1.14. API connection details will be handled externally in a shared utility module similar +to how other cloud modules operate. + +## Parameters + +Docker_network_facts will accept the parameters listed below. API connection parameters will be part of a shared +utility module as mentioned above. + +``` +name: + description: + - Network name or list of network names. + default: null + +``` + + +## Examples + +``` +- name: Inspect all networks + docker_network_facts + register: network_facts + +- name: Inspect a specific network and format the output + docker_network_facts + name: web_app + register: web_app_facts +``` + +# Returns + +``` +{ + changed: False + failed: False + rc: 0 + results: [ < inspection output > ] +} +``` diff --git a/docs/proposals/docker/docker_network_module.md b/docs/proposals/docker/docker_network_module.md new file mode 100644 index 00000000000..92e085c29fa --- /dev/null +++ b/docs/proposals/docker/docker_network_module.md @@ -0,0 +1,130 @@ +# Docker_Network Module Proposal + +## Purpose and Scope: + +The purpose of Docker_network is to create networks, connect containers to networks, disconnect containers from +networks, and delete networks. + +Docker network will manage networks using docker-py to communicate with either a local or remote API. It will +support API versions >= 1.14. API connection details will be handled externally in a shared utility module similar to +how other cloud modules operate. + +## Parameters: + +Docker_network will accept the parameters listed below. Parameters related to connecting to the API will be handled in +a shared utility module, as mentioned above. + +``` +connected: + description: + - List of container names or container IDs to connect to a network. + default: null + +driver: + description: + - Specify the type of network. Docker provides bridge and overlay drivers, but 3rd party drivers can also be used. + default: bridge + +driver_options: + description: + - Dictionary of network settings. Consult docker docs for valid options and values. + default: null + +force: + description: + - With state 'absent' forces disconnecting all containers from the network prior to deleting the network. With + state 'present' will disconnect all containers, delete the network and re-create the network. + default: false + +incremental: + description: + - By default the connected list is canonical, meaning containers not on the list are removed from the network. + Use incremental to leave existing containers connected. + default: false + +ipam_driver: + description: + - Specifiy an IPAM driver. + default: null + +ipam_options: + description: + - Dictionary of IPAM options. + default: null + +network_name: + description: + - Name of the network to operate on. + default: null + required: true + +state: + description: + - "absent" deletes the network. If a network has connected containers, it cannot be deleted. Use the force option + to disconnect all containers and delete the network. + - "present" creates the network, if it does not already exist with the specified parameters, and connects the list + of containers provided via the connected parameter. Containers not on the list will be disconnected. An empty + list will leave no containers connected to the network. Use the incremental option to leave existing containers + connected. Use the force options to force re-creation of the network. + default: present + choices: + - absent + - present +``` + + +## Examples: + +``` +- name: Create a network + docker_network: + name: network_one + +- name: Remove all but selected list of containers + docker_network: + name: network_one + connected: + - containera + - containerb + - containerc + +- name: Remove a single container + docker_network: + name: network_one + connected: "{{ fulllist|difference(['containera']) }}" + +- name: Add a container to a network, leaving existing containers connected + docker_network: + name: network_one + connected: + - containerc + incremental: yes + +- name: Create a network with options (Not sure if 'ip_range' is correct key name) + docker_network + name: network_two + options: + subnet: '172.3.26.0/16' + gateway: 172.3.26.1 + ip_range: '192.168.1.0/24' + +- name: Delete a network, disconnecting all containers + docker_network: + name: network_one + state: absent + force: yes +``` + +## Returns: + +``` +{ + changed: True, + failed: false + rc: 0 + action: created | removed | none + results: { + < results from docker inspect for the affected network > + } +} +``` diff --git a/docs/proposals/docker/docker_volume_facts.md b/docs/proposals/docker/docker_volume_facts.md new file mode 100644 index 00000000000..119df27e337 --- /dev/null +++ b/docs/proposals/docker/docker_volume_facts.md @@ -0,0 +1,48 @@ + +# Docker_Volume_Facts Module Proposal + +## Purpose and Scope + +Docker_volume_facts will inspect volumes. + +Docker_volume_facts will use docker-py to communicate with either a local or remote API. It will +support API versions >= 1.14. API connection details will be handled externally in a shared utility module similar +to how other cloud modules operate. + +## Parameters + +Docker_volume_facts will accept the parameters listed below. API connection parameters will be part of a shared +utility module as mentioned above. + + +``` +name: + description: + - Volume name or list of volume names. + default: null +``` + + +## Examples + +``` +- name: Inspect all volumes + docker_volume_facts + register: volume_facts + +- name: Inspect a specific volume + docker_volume_facts: + name: data + register: data_vol_facts +``` + +# Returns + +``` +{ + changed: False + failed: False + rc: 0 + results: [ < output from volume inspection > ] +} +``` \ No newline at end of file diff --git a/docs/proposals/docker/docker_volume_module.md b/docs/proposals/docker/docker_volume_module.md new file mode 100644 index 00000000000..4a9d5e47a81 --- /dev/null +++ b/docs/proposals/docker/docker_volume_module.md @@ -0,0 +1,82 @@ +# Docker_Volume Modules Proposal + +## Purpose and Scope + +The purpose of docker_volume is to manage volumes. + +Docker_volume will manage volumes using docker-py to communicate with either a local or remote API. It will +support API versions >= 1.14. API connection details will be handled externally in a shared utility module similar +to how other cloud modules operate. + +## Parameters + +Docker_volume accepts the parameters listed below. Parameters for connecting to the API are not listed here, as they +will be part of the shared module mentioned above. + +``` +driver: + description: + - Volume driver. + default: local + +force: + description: + - Use with state 'present' to force removal and re-creation of an existing volume. This will not remove and + re-create the volume if it is already in use. + +name: + description: + - Name of the volume. + required: true + default: null + +options: + description: + - Dictionary of driver specific options. The local driver does not currently support + any options. + default: null + +state: + description: + - "absent" removes a volume. A volume cannot be removed if it is in use. + - "present" create a volume with the specified name, if the volume does not already exist. Use the force + option to remove and re-create a volume. Even with the force option a volume cannot be removed and re-created if + it is in use. + default: present + choices: + - absent + - present +``` + +## Examples + +``` +- name: Create a volume + docker_volume: + name: data + +- name: Remove a volume + docker_volume: + name: data + state: absent + +- name: Re-create an existing volume + docker_volume: + name: data + state: present + force: yes +``` + +## Returns + +``` +{ + changed: true, + failed: false, + rc: 0, + action: removed | created | none + results: { + < show the result of docker inspect of an affected volume > + } +} +``` \ No newline at end of file diff --git a/docs/proposals/proposals_process_proposal.MD b/docs/proposals/proposals_process_proposal.MD new file mode 100644 index 00000000000..eb83eeb1b99 --- /dev/null +++ b/docs/proposals/proposals_process_proposal.MD @@ -0,0 +1,110 @@ +# Proposal: Proposals - have a process and documentation + +*Author*: Robyn Bergeron <@robynbergeron> + +*Date*: 04/03/2016 + +- Status: New +- Proposal type: community development process +- Targeted Release: Forever, until we improve it more at a later date. +- PR for Comments: https://github.com/ansible/ansible/pull/14802# +- Estimated time to implement: 2 weeks at most + +Comments on this proposal prior to acceptance are accepted in the comments section of the pull request linked above. + +## Motivation +Define light process for how proposals are created and accepted, and document the process permanently in community.html somewhere. + +The following suggested process was created with the following ideas in mind: +- Transparency: notifications, decisions made in public meetings, etc. helps people to know what is going on. +- Avoid proliferation of multiple comments in multiple places; keep everything in the PR. +- Action is being taken: Knowing when and where decisions are made, and knowing who is the final authority, gives people the sense that things are moving. +- Ensure that new features or enhancements are added to the roadmap and release notes. + +### Problems +Proposals are confusing. Should I write one? Where do I put it? Why can’t I find any documentation about this? Who approves things? This is why we should have a light and unbureaucratic process. + +## Solution proposal +This proposal has multiple parts: +- Proposed process for submitting / accepting proposals +- Suggested proposal template + +Once the process and template are approved, a PR will be submitted for documenting the process permanently in documentation, as well as a PR to ansible/docs/proposals for the proposal template. + +### Proposed Process +1: PROPOSAL CREATION +- Person making the proposal creates the proposal document in ansible/proposals via PR, following the proposal template/ +- Person making the proposal creates an issue in ansible/proposals for that proposal. +- Author of proposal PR updates the proposal with link to the created issue #. +- Notify the community that this proposal exists. +- Author notifies ansible-devel mailing list for transparency, providing link to issue. +- Author includes commentary indicating that comments should *not* be in response to this email, but rather, community members should add comments or feedback in the issue. +- PRs may be made to the proposal, and can merged or not at submitter's discretion, and should be discussed/linked in the issue. + +2: KEEP THE PROPOSAL MOVING TOWARDS A DECISION. +- Create tags in the ansible/proposals repo to indicate progress of the various proposal issues; ie: Discussion, Ready for meeting, Approved. (Can be used in conjunction with a board on waffle.io to show this, kanban style.) +- Proposals use public meetings as a mechanism to keep them moving. +- All proposals are decided on in a public meeting by a combination of folks with commit access to Ansible and any interested parties / users, as well as the author of the proposal. Time for approvals will be a portion of the overall schedule; proposals will be reviewed in the order received and may occasionally be deferred to the next meeting. If we are overwhelmed, a separate meeting may be scheduled. + +(Note: ample feedback in the comments of the proposal issue should allow for folks to come to broad consensus in one way or another in the meeting rather rapidly, generally without an actual counted vote. However, the decision should be made *in the meeting*, so as to avoid any questions around whether or not the approval of one Ansible maintain / committer reflects the opinions or decision of everyone.) + +- *New* proposals are explicitly added to the public IRC meeting agenda for each week by the meeting organizer for for acknowledgement of ongoing discussion and existence, and/or easy approval/rejection. (Either via a separate issue somewhere tracking any meeting items, or by adding a “meeting” label to the PR.) +- Existing new, not-yet-approved proposals are reviewed weekly by meeting organizer to check for slow-moving/stalled proposals, or for flags from the proposal owner indicating that they'd like to have it addressed in the weeks meeting + +3: PROPOSAL APPROVED +- Amendments needed to the proposal after IRC discussion should be made immediately. +- The proposal status should be changed to Approved / In Progress in the document. +- The proposal should be moved from /ansible/proposals to a roadmap folder (or similar). +- The proposal issue comments should be updated with a note by the meeting organizer that the proposal has been accepted, and further commentary should be in the PRs implementing the code itself. +- Proposals can also be PENDING or NEEDS INFO (waiting on something), or DECLINED. + +4: CODE IN PROGRESS +- Approved proposals should be periodically checked for progress, especially if tied to a release and/or is noted as release blocking. +- PRs implementing the proposal are recommended to link to the original proposal PR or document for context. +5: CODE COMPLETE +- Proposal document, which should be in docs/roadmap, should have their status updated to COMPLETE. +- The release notes file for the targeted release should be updated with a small note regarding the feature or enhancement; completed proposals for community processes should have a follow-up mail sent to the mailing list providing information and links to the new process. +- Hooray! Buy your friend a tasty beverage of their choosing. + +### Suggested Proposal Template Outline +Following the .md convention, a proposal template should go in the docs/proposals repository. This is a suggested outline; the template will provide more guidance / context and will be submitted as a PR upon approval of this proposal. + +Please note that, in line with the above guidance that some processes will require fine-tuning over time, that the suggested template outline below, as well as the final submitted template to the docs/proposals repo has wiggle room in terms of description, and that what makes sense may vary from one proposal to another. The expectation is that people will simply do what seems right, and over time we’ll figure out what works best — but in the meantime, guidance is nice. + +#### TEMPLATE OUTLINE +- Proposal Title +- Author (w/github ID linked) +- Date: + +- Status: New, Approved, Pending, Complete +- Proposal type: Feature / enhancement / community development process +- Targeted Release: +- PR for comments: +- Estimated time to implement: + +Comments on this proposal prior to acceptance are accepted in the comments of the PR linked above. + +- Motivation / Problems solved: +- Proposed Solution: (what you’re doing, and why; keeping this loose for now.) + +Other Suggested things to include: +- Dependencies / requirements: +- Testing: +- Documentation: + +## Dependencies / requirements + +- Approval of this proposed process is needed to create the actual documentation of the process. +- Weekly, public IRC meetings (which should probably be documented Wrt time / day of week / etc. in the contributor documentation) of the Ansible development community. +- Creation of appropriate labels in GitHub (or defining some other mechanism to gather items for a weekly meeting agenda, such as a separate issue in GitHub that links to the PRs.) +- Coming to an agreement regarding “what qualifies as a feature or enhancement that requires a proposal, vs. just submitting a PR with code.” It could simply be that if the change is large or very complicated, our recommendation is always to file a proposal to ensure (a) transparency (b) that a contributor doesn’t waste their time on something that ultimately can’t be merged at this time. +- Nice to have: Any new proposal PR landing in ansible/proposals is automatically merged and an email automatically notifies the mailing list of the existence and location of the proposal & related issue # for comments. + +## Testing + +Testing of this proposal will literally be via submitting this proposal through the proposed proposal process. If it fails miserably, we’ll know it needs fine-tuning or needs to go in the garbage can. + +## Documentation: + +- Documentation of the process, including “what is a feature or enhancement vs. just a regular PR,” along with the steps shown above, will be added to the Ansible documentation in .rst format via PR. The documentation should also provide guidance on the standard wording of the email notifying ansible-devel list that the proposal exists and is ready for review in the issue comments. +- A proposal template should also be created in the ansible/proposals repo directory. diff --git a/docs/proposals/publish-subscribe.md b/docs/proposals/publish-subscribe.md new file mode 100644 index 00000000000..f31d2dca33d --- /dev/null +++ b/docs/proposals/publish-subscribe.md @@ -0,0 +1,205 @@ +# Publish / Subscribe for Handlers + +*Author*: René Moser <@resmo> + +*Date*: 07/03/2016 + +## Motivation + +In some use cases a publish/subscribe kind of event to run a handler is more convenient, e.g. restart services after replacing SSL certs. + +However, ansible does not provide a built-in way to handle it yet. + + +### Problem + +If your SSL cert changes, you usually have to reload/restart services to use the new certificate. + +However, If you have a ssl role or a generic ssl play, you usually don't want to add specific handlers to it. +Instead it would be much more convenient to use a publish/subscribe kind of paradigm in the roles where the services are configured in. + +The way we implemented it currently: + +I use notify to set a fact where later (in different plays) we act on a fact using notify again. + +~~~yaml +--- +- hosts: localhost + gather_facts: no + tasks: + - name: copy an ssl cert + shell: echo cert has been changed + notify: publish ssl cert change + handlers: + - name: publish ssl cert change + set_fact: + ssl_cert_changed: true + +- hosts: localhost + gather_facts: no + tasks: + - name: subscribe for ssl cert change + shell: echo cert changed + notify: service restart one + when: ssl_cert_changed is defined and ssl_cert_changed + handlers: + - name: service restart one + shell: echo service one restarted + +- hosts: localhost + gather_facts: no + tasks: + - name: subscribe for ssl cert change + shell: echo cert changed + when: ssl_cert_changed is defined and ssl_cert_changed + notify: service restart two + handlers: + - name: service restart two + shell: echo service two restarted +~~~ + +However, this looks like a workaround of a feature that ansible should provide in a much cleaner way. + +## Approaches + +### Approach 1: + +Provide new `subscribe` keyword on handlers: + +~~~yaml +- hosts: localhost + gather_facts: no + tasks: + - name: copy an ssl cert + shell: echo cert has been changed + + +- hosts: localhost + gather_facts: no + handlers: + - name: service restart one + shell: echo service one restarted + subscribe: copy an ssl cert + + +- hosts: localhost + gather_facts: no + handlers: + - name: service restart two + shell: echo service two restarted + subscribe: copy an ssl cert +~~~ + +### Approach 2: + +Provide new `subscribe` on handlers and `publish` keywords in tasks: + +~~~yaml +- hosts: localhost + gather_facts: no + tasks: + - name: copy an ssl cert + shell: echo cert has been changed + publish: yes + + +- hosts: localhost + gather_facts: no + handlers: + - name: service restart one + shell: echo service one restarted + subscribe: copy an ssl cert + + +- hosts: localhost + gather_facts: no + handlers: + - name: service restart two + shell: echo service two restarted + subscribe: copy an ssl cert +~~~ + +### Approach 3: + +Provide new `subscribe` module: + +A subscribe module could consume the results of a task by name, optionally the value to react on could be specified (default: `changed`) + +~~~yaml +- hosts: localhost + gather_facts: no + tasks: + - name: copy an ssl cert + shell: echo cert has been changed + + +- hosts: localhost + gather_facts: no + tasks: + - subscribe: + name: copy an ssl cert + notify: service restart one + handlers: + - name: service restart one + shell: echo service one restarted + + +- hosts: localhost + gather_facts: no + tasks: + - subscribe: + name: copy an ssl cert + react_on: changed + notify: service restart two + handlers: + - name: service restart two + shell: echo service two restarted +~~~ + + +### Approach 4: + +Provide new `subscribe` module (same as Approach 3) and `publish` keyword: + +~~~yaml +- hosts: localhost + gather_facts: no + tasks: + - name: copy an ssl cert + shell: echo cert has been changed + publish: yes + + +- hosts: localhost + gather_facts: no + tasks: + - subscribe: + name: copy an ssl cert + notify: service restart one + handlers: + - name: service restart one + shell: echo service one restarted + + +- hosts: localhost + gather_facts: no + tasks: + - subscribe: + name: copy an ssl cert + notify: service restart two + handlers: + - name: service restart two + shell: echo service two restarted +~~~ + +### Clarifications about role dependencies and publish + +When using service roles having the subscription handlers and the publish task (e.g. cert change) is defined in a depended role (SSL role) only the first service role running the "cert change" task as dependency will trigger the publish. + +In any other service role in the playbook having "SSL role" as dependency, the task won't be `changed` anymore. + +Therefore a once published "message" should not be overwritten or so called "unpublished" by running the same task in a followed role in the playbook. + +## Conclusion + +Feedback is requested to improve any of the above approaches, or provide further approaches to solve this problem. diff --git a/docs/proposals/re-run-handlers.md b/docs/proposals/re-run-handlers.md new file mode 100644 index 00000000000..9b5a01df8fa --- /dev/null +++ b/docs/proposals/re-run-handlers.md @@ -0,0 +1,77 @@ +# Proposal: Re-run handlers cli option + +*Author*: René Moser <@resmo> + +*Date*: 07/03/2016 + +- Status: New + +## Motivation + +The most annoying thing users face using ansible in production is running handlers manually after a task failed after a notified handler. + +### Problems + +Handler notifications get lost after a task failed and there is no help from ansible to catch up the notified handlers in a next ansible playbook run. + +~~~yaml +- hosts: localhost + gather_facts: no + tasks: + - name: simple task + shell: echo foo + notify: get msg out + + - name: this tasks fails + fail: msg="something went wrong" + + handlers: + - name: get msg out + shell: echo handler run +~~~ + +Result: + +~~~ +$ ansible-playbook test.yml + +PLAY *************************************************************************** + +TASK [simple task] ************************************************************* +changed: [localhost] + +TASK [this tasks fails] ******************************************************** +fatal: [localhost]: FAILED! => {"changed": false, "failed": true, "msg": "something went wrong"} + +NO MORE HOSTS LEFT ************************************************************* + +RUNNING HANDLER [get msg out] ************************************************** + to retry, use: --limit @test.retry + +PLAY RECAP ********************************************************************* +localhost : ok=1 changed=1 unreachable=0 failed=1 +~~~ + +## Solution proposal + +Similar to retry, ansible should provide a way to manully invoke a list of handlers additionaly to the notified handlers in the plays: + +~~~ + $ ansible-playbook test.yml --notify-handlers ,, + $ ansible-playbook test.yml --notify-handlers @test.handlers +~~~ + +Example: + +~~~ + $ ansible-playbook test.yml --notify-handlers "get msg out" +~~~ + +The stdout of a failed play should provide an example how to run notified handlers in the next run: + +~~~ +... +RUNNING HANDLER [get msg out] ************************************************** + to retry, use: --limit @test.retry --notify-handlers @test.handlers +~~~ + diff --git a/docs/proposals/rename_always_run.md b/docs/proposals/rename_always_run.md new file mode 100644 index 00000000000..e3c05d7a8d7 --- /dev/null +++ b/docs/proposals/rename_always_run.md @@ -0,0 +1,34 @@ +# Rename always_run to ignore_checkmode + +*Author*: René Moser <@resmo> + +*Date*: 02/03/2016 + +## Motivation + +The task argument `always_run` is misleading. + +Ansible is known to be readable by users without deep knowledge of creating playbooks, they do not understand +what `always_run` does at the first glance. + +### Problems + +The following looks scary if you have no idea, what `always_run` does: + +``` +- shell: dangerous_cleanup.sh + when: cleanup == "yes" + always_run: yes +``` + +You have a conditional but also a word that says `always`. This is a conflict in terms of understanding. + +## Solution Proposal + +Deprecate `always_run` by rename it to `ignore_checkmode`: + +``` +- shell: dangerous_cleanup.sh + when: cleanup == "yes" + ignore_checkmode: yes +``` diff --git a/docsite/Makefile b/docsite/Makefile index 92129f78514..f7f5e533271 100644 --- a/docsite/Makefile +++ b/docsite/Makefile @@ -1,10 +1,11 @@ #!/usr/bin/make SITELIB = $(shell python -c "from distutils.sysconfig import get_python_lib; print get_python_lib()") FORMATTER=../hacking/module_formatter.py +DUMPER=../hacking/dump_playbook_attributes.py all: clean docs -docs: clean modules staticmin +docs: clean directives modules staticmin ./build-site.py -(cp *.ico htmlout/) -(cp *.jpg htmlout/) @@ -20,6 +21,8 @@ viewdocs: clean staticmin htmldocs: staticmin ./build-site.py rst +webdocs: htmldocs + clean: -rm -rf htmlout -rm -f .buildinfo @@ -39,8 +42,11 @@ clean: .PHONEY: docs clean +directives: $(FORMATTER) ../hacking/templates/rst.j2 + PYTHONPATH=../lib $(DUMPER) --template-dir=../hacking/templates --output-dir=rst/ + modules: $(FORMATTER) ../hacking/templates/rst.j2 PYTHONPATH=../lib $(FORMATTER) -t rst --template-dir=../hacking/templates --module-dir=../lib/ansible/modules -o rst/ staticmin: - cat _themes/srtd/static/css/theme.css | sed -e 's/^[ \t]*//g; s/[ \t]*$$//g; s/\([:{;,]\) /\1/g; s/ {/{/g; s/\/\*.*\*\///g; /^$$/d' | sed -e :a -e '$$!N; s/\n\(.\)/\1/; ta' > _themes/srtd/static/css/theme.min.css + cat _themes/srtd/static/css/theme.css | sed -e 's/^[ ]*//g; s/[ ]*$$//g; s/\([:{;,]\) /\1/g; s/ {/{/g; s/\/\*.*\*\///g; /^$$/d' | sed -e :a -e '$$!N; s/\n\(.\)/\1/; ta' > _themes/srtd/static/css/theme.min.css diff --git a/docsite/_themes/srtd/footer.html b/docsite/_themes/srtd/footer.html index b70cfde7ad8..dc1d70a4d1f 100644 --- a/docsite/_themes/srtd/footer.html +++ b/docsite/_themes/srtd/footer.html @@ -12,8 +12,17 @@
+ +

- © Copyright 2015 Ansible, Inc.. + © Copyright 2016 Ansible, Inc.. {%- if last_updated %} {% trans last_updated=last_updated|e %}Last updated on {{ last_updated }}.{% endtrans %} diff --git a/docsite/_themes/srtd/layout.html b/docsite/_themes/srtd/layout.html index 16f0d8d2663..cb532191e6e 100644 --- a/docsite/_themes/srtd/layout.html +++ b/docsite/_themes/srtd/layout.html @@ -150,11 +150,6 @@ -

-