',
+ action='store',
+ )
+ args = parser.parse_args()
+
+ if not args.list_ and not args.host: # Require at least one option
+ parser.exit(status=1, message='No action requested')
+
+ if args.list_ and args.host: # Do not allow multiple options
+ parser.exit(status=1, message='Too many actions requested')
+
+ return args
+
+
+def main():
+ '''Set up argument handling and callback routing'''
+ args = parse_args()
+ client = NSoTInventory()
+
+ # Callback condition
+ if args.list_:
+ print(client.do_list())
+ elif args.host:
+ print(client.do_host(args.host))
+
+if __name__ == '__main__':
+ main()
diff --git a/contrib/inventory/nsot.yaml b/contrib/inventory/nsot.yaml
new file mode 100644
index 0000000000..ebddbc8234
--- /dev/null
+++ b/contrib/inventory/nsot.yaml
@@ -0,0 +1,22 @@
+---
+juniper_routers:
+ query: 'deviceType=ROUTER manufacturer=JUNIPER'
+ vars:
+ group: juniper_routers
+ netconf: true
+ os: junos
+
+cisco_asa:
+ query: 'manufacturer=CISCO deviceType=FIREWALL'
+ vars:
+ group: cisco_asa
+ routed_vpn: false
+ stateful: true
+
+old_cisco_asa:
+ query: 'manufacturer=CISCO deviceType=FIREWALL -softwareVersion=8.3+'
+ vars:
+ old_nat: true
+
+not_f10:
+ query: '-manufacturer=FORCE10'
diff --git a/contrib/inventory/openstack.py b/contrib/inventory/openstack.py
index 46b43e9221..b82a042c29 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:
@@ -106,23 +114,44 @@ def get_host_groups(inventory):
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:
+ server = servers[0]
+ hostvars[name] = dict(
+ ansible_ssh_host=server['interface_ip'],
+ openstack=server)
+ for group in get_groups_from_server(server, namegroup=False):
+ groups[group].append(server['name'])
+ else:
+ for server in servers:
+ server_id = server['id']
+ hostvars[server_id] = dict(
+ ansible_ssh_host=server['interface_ip'],
+ openstack=server)
+ for group in get_groups_from_server(server, namegroup=True):
+ groups[group].append(server_id)
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 refresh:
+ return True
if os.path.isfile(cache_file):
mod_time = os.path.getmtime(cache_file)
current_time = time.time()
@@ -169,14 +198,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 a99bb02058..1520e2937e 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/rax.ini b/contrib/inventory/rax.ini
index 5a269e16a3..15948e7b2e 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 0028f54d20..4ac6b0f47e 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/docs/man/man1/ansible-galaxy.1.asciidoc.in b/docs/man/man1/ansible-galaxy.1.asciidoc.in
index e6f2d0b456..9ffe65e45a 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 5686162f21..82181982fb 100644
--- a/docs/man/man1/ansible-playbook.1.asciidoc.in
+++ b/docs/man/man1/ansible-playbook.1.asciidoc.in
@@ -96,7 +96,7 @@ 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'::
diff --git a/docs/man/man1/ansible-pull.1.asciidoc.in b/docs/man/man1/ansible-pull.1.asciidoc.in
index 333b8e34e0..0afba2aeaa 100644
--- a/docs/man/man1/ansible-pull.1.asciidoc.in
+++ b/docs/man/man1/ansible-pull.1.asciidoc.in
@@ -95,6 +95,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/docsite/Makefile b/docsite/Makefile
index 92129f7851..2b87827c59 100644
--- a/docsite/Makefile
+++ b/docsite/Makefile
@@ -20,6 +20,8 @@ viewdocs: clean staticmin
htmldocs: staticmin
./build-site.py rst
+webdocs: htmldocs
+
clean:
-rm -rf htmlout
-rm -f .buildinfo
@@ -43,4 +45,4 @@ 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 b70cfde7ad..dc1d70a4d1 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 f4d7a8a536..cb532191e6 100644
--- a/docsite/_themes/srtd/layout.html
+++ b/docsite/_themes/srtd/layout.html
@@ -150,11 +150,6 @@
-
-
- {% include "searchbox.html" %}
-
-