generate rst doc pages for command line tools (#27530)
* let generate_man also gen rst pages for cli tools * make template-file, output-dir, output format cli options for generate_man * update main Makefile to use generate_man.py for docs (man pages and rst) * update vault docs that use :option: * Edits based on6e34ea6242
anda3afc78535
* add a optparse 'desc' to lib/ansible/cli/config.py The man page needs a short desc for the 'NAME' field which it gets from the option parse 'desc' value. Fixes building ansible-config man page. * add trim_docstring from pep257 to generate_man use pep258 docstring trim function to fix up any indention weirdness inherit to doc strings (ie, lines other than first line being indented. * Add refs to cli command actions To reference ansible-vaults --vault-id option, use: :option:`The link text here <ansible-vault --vault-id>` or: :option:`--vault-id <ansible-vault --vault-id>` To reference ansible-vault's 'encrypt' action, use: :ref:`The link text here <ansible_vault_encrypt>` or most of the time: :ref:`ansible-vault encrypt <ansible_vault_encrypt>`
This commit is contained in:
parent
4a73390823
commit
89c973445c
9 changed files with 404 additions and 82 deletions
6
Makefile
6
Makefile
|
@ -29,6 +29,7 @@ ASCII2HTMLMAN = a2x -L -D docs/html/man/ -d manpage -f xhtml
|
||||||
else
|
else
|
||||||
ASCII2MAN = @echo "ERROR: AsciiDoc 'a2x' command is not installed but is required to build $(MANPAGES)" && exit 1
|
ASCII2MAN = @echo "ERROR: AsciiDoc 'a2x' command is not installed but is required to build $(MANPAGES)" && exit 1
|
||||||
endif
|
endif
|
||||||
|
GENERATE_CLI = docs/bin/generate_man.py
|
||||||
|
|
||||||
PYTHON=python
|
PYTHON=python
|
||||||
SITELIB = $(shell $(PYTHON) -c "from distutils.sysconfig import get_python_lib; print get_python_lib()")
|
SITELIB = $(shell $(PYTHON) -c "from distutils.sysconfig import get_python_lib; print get_python_lib()")
|
||||||
|
@ -343,8 +344,9 @@ webdocs:
|
||||||
|
|
||||||
.PHONY: generate_asciidoc
|
.PHONY: generate_asciidoc
|
||||||
generate_asciidoc: lib/ansible/cli/*.py
|
generate_asciidoc: lib/ansible/cli/*.py
|
||||||
mkdir -p ./docs/man/man1/
|
mkdir -p ./docs/man/man1/ ; \
|
||||||
PYTHONPATH=./lib ./docs/bin/generate_man.py
|
PYTHONPATH=./lib $(GENERATE_CLI) --template-file=docs/templates/man.j2 --output-dir=docs/man/man1/ --output-format man lib/ansible/cli/*.py
|
||||||
|
|
||||||
|
|
||||||
docs: generate_asciidoc
|
docs: generate_asciidoc
|
||||||
make $(MANPAGES)
|
make $(MANPAGES)
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
import optparse
|
||||||
import os
|
import os
|
||||||
|
import pprint
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
from jinja2 import Environment, FileSystemLoader
|
from jinja2 import Environment, FileSystemLoader
|
||||||
|
@ -8,6 +10,46 @@ from jinja2 import Environment, FileSystemLoader
|
||||||
from ansible.module_utils._text import to_bytes
|
from ansible.module_utils._text import to_bytes
|
||||||
|
|
||||||
|
|
||||||
|
def generate_parser():
|
||||||
|
p = optparse.OptionParser(
|
||||||
|
version='%prog 1.0',
|
||||||
|
usage='usage: %prog [options]',
|
||||||
|
description='Generate cli documentation from cli docstrings',
|
||||||
|
)
|
||||||
|
|
||||||
|
p.add_option("-t", "--template-file", action="store", dest="template_file", default="../templates/man.j2", help="path to jinja2 template")
|
||||||
|
p.add_option("-o", "--output-dir", action="store", dest="output_dir", default='/tmp/', help="Output directory for rst files")
|
||||||
|
p.add_option("-f", "--output-format", action="store", dest="output_format", default='man', help="Output format for docs (the default 'man' or 'rst')")
|
||||||
|
return p
|
||||||
|
|
||||||
|
|
||||||
|
# from https://www.python.org/dev/peps/pep-0257/
|
||||||
|
def trim_docstring(docstring):
|
||||||
|
if not docstring:
|
||||||
|
return ''
|
||||||
|
# Convert tabs to spaces (following the normal Python rules)
|
||||||
|
# and split into a list of lines:
|
||||||
|
lines = docstring.expandtabs().splitlines()
|
||||||
|
# Determine minimum indentation (first line doesn't count):
|
||||||
|
indent = sys.maxint
|
||||||
|
for line in lines[1:]:
|
||||||
|
stripped = line.lstrip()
|
||||||
|
if stripped:
|
||||||
|
indent = min(indent, len(line) - len(stripped))
|
||||||
|
# Remove indentation (first line is special):
|
||||||
|
trimmed = [lines[0].strip()]
|
||||||
|
if indent < sys.maxint:
|
||||||
|
for line in lines[1:]:
|
||||||
|
trimmed.append(line[indent:].rstrip())
|
||||||
|
# Strip off trailing and leading blank lines:
|
||||||
|
while trimmed and not trimmed[-1]:
|
||||||
|
trimmed.pop()
|
||||||
|
while trimmed and not trimmed[0]:
|
||||||
|
trimmed.pop(0)
|
||||||
|
# Return a single string:
|
||||||
|
return '\n'.join(trimmed)
|
||||||
|
|
||||||
|
|
||||||
def get_options(optlist):
|
def get_options(optlist):
|
||||||
''' get actual options '''
|
''' get actual options '''
|
||||||
|
|
||||||
|
@ -24,107 +66,215 @@ def get_options(optlist):
|
||||||
return opts
|
return opts
|
||||||
|
|
||||||
|
|
||||||
|
def get_option_groups(option_parser):
|
||||||
|
groups = []
|
||||||
|
for option_group in option_parser.option_groups:
|
||||||
|
group_info = {}
|
||||||
|
group_info['desc'] = option_group.get_description()
|
||||||
|
group_info['options'] = option_group.option_list
|
||||||
|
group_info['group_obj'] = option_group
|
||||||
|
groups.append(group_info)
|
||||||
|
return groups
|
||||||
|
|
||||||
|
|
||||||
def opt_doc_list(cli):
|
def opt_doc_list(cli):
|
||||||
''' iterate over options lists '''
|
''' iterate over options lists '''
|
||||||
|
|
||||||
results = []
|
results = []
|
||||||
for optg in cli.parser.option_groups:
|
for option_group in cli.parser.option_groups:
|
||||||
results.extend(get_options(optg.option_list))
|
results.extend(get_options(option_group.option_list))
|
||||||
|
|
||||||
results.extend(get_options(cli.parser.option_list))
|
results.extend(get_options(cli.parser.option_list))
|
||||||
|
|
||||||
return results
|
return results
|
||||||
|
|
||||||
|
|
||||||
def opts_docs(cli, name):
|
# def opts_docs(cli, name):
|
||||||
|
def opts_docs(cli_class_name, cli_module_name):
|
||||||
''' generate doc structure from options '''
|
''' generate doc structure from options '''
|
||||||
|
|
||||||
# cli name
|
cli_name = 'ansible-%s' % cli_module_name
|
||||||
if '-' in name:
|
if cli_module_name == 'adhoc':
|
||||||
name = name.split('-')[1]
|
cli_name = 'ansible'
|
||||||
else:
|
|
||||||
name = 'adhoc'
|
|
||||||
|
|
||||||
# cli info
|
# WIth no action/subcommand
|
||||||
|
# shared opts set
|
||||||
|
# instantiate each cli and ask its options
|
||||||
|
cli_klass = getattr(__import__("ansible.cli.%s" % cli_module_name,
|
||||||
|
fromlist=[cli_class_name]), cli_class_name)
|
||||||
|
cli = cli_klass([])
|
||||||
|
|
||||||
|
# parse the common options
|
||||||
|
try:
|
||||||
|
cli.parse()
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
# base/common cli info
|
||||||
docs = {
|
docs = {
|
||||||
'cli': name,
|
'cli': cli_module_name,
|
||||||
|
'cli_name': cli_name,
|
||||||
'usage': cli.parser.usage,
|
'usage': cli.parser.usage,
|
||||||
'short_desc': cli.parser.description,
|
'short_desc': cli.parser.description,
|
||||||
'long_desc': cli.__doc__,
|
'long_desc': trim_docstring(cli.__doc__),
|
||||||
|
'actions': {},
|
||||||
}
|
}
|
||||||
|
option_info = {'option_names': [],
|
||||||
|
'options': [],
|
||||||
|
'groups': []}
|
||||||
|
|
||||||
|
for extras in ('ARGUMENTS'):
|
||||||
|
if hasattr(cli, extras):
|
||||||
|
docs[extras.lower()] = getattr(cli, extras)
|
||||||
|
|
||||||
|
common_opts = opt_doc_list(cli)
|
||||||
|
groups_info = get_option_groups(cli.parser)
|
||||||
|
shared_opt_names = []
|
||||||
|
for opt in common_opts:
|
||||||
|
shared_opt_names.extend(opt.get('options', []))
|
||||||
|
|
||||||
|
option_info['options'] = common_opts
|
||||||
|
option_info['option_names'] = shared_opt_names
|
||||||
|
|
||||||
|
option_info['groups'].extend(groups_info)
|
||||||
|
|
||||||
|
docs.update(option_info)
|
||||||
|
|
||||||
|
# now for each action/subcommand
|
||||||
# force populate parser with per action options
|
# force populate parser with per action options
|
||||||
if cli.VALID_ACTIONS:
|
|
||||||
docs['actions'] = {}
|
# use class attrs not the attrs on a instance (not that it matters here...)
|
||||||
|
for action in getattr(cli_klass, 'VALID_ACTIONS', ()):
|
||||||
|
# instantiate each cli and ask its options
|
||||||
|
action_cli_klass = getattr(__import__("ansible.cli.%s" % cli_module_name,
|
||||||
|
fromlist=[cli_class_name]), cli_class_name)
|
||||||
|
# init with args with action added?
|
||||||
|
cli = action_cli_klass([])
|
||||||
|
cli.args.append(action)
|
||||||
|
|
||||||
|
try:
|
||||||
|
cli.parse()
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
# FIXME/TODO: needed?
|
||||||
# avoid dupe errors
|
# avoid dupe errors
|
||||||
cli.parser.set_conflict_handler('resolve')
|
cli.parser.set_conflict_handler('resolve')
|
||||||
for action in cli.VALID_ACTIONS:
|
|
||||||
cli.args.append(action)
|
cli.set_action()
|
||||||
cli.set_action()
|
|
||||||
docs['actions'][action] = getattr(cli, 'execute_%s' % action).__doc__
|
action_info = {'option_names': [],
|
||||||
|
'options': []}
|
||||||
|
# docs['actions'][action] = {}
|
||||||
|
# docs['actions'][action]['name'] = action
|
||||||
|
action_info['name'] = action
|
||||||
|
action_info['desc'] = trim_docstring(getattr(cli, 'execute_%s' % action).__doc__)
|
||||||
|
|
||||||
|
# docs['actions'][action]['desc'] = getattr(cli, 'execute_%s' % action).__doc__.strip()
|
||||||
|
action_doc_list = opt_doc_list(cli)
|
||||||
|
|
||||||
|
uncommon_options = []
|
||||||
|
for action_doc in action_doc_list:
|
||||||
|
# uncommon_options = []
|
||||||
|
|
||||||
|
option_aliases = action_doc.get('options', [])
|
||||||
|
for option_alias in option_aliases:
|
||||||
|
|
||||||
|
if option_alias in shared_opt_names:
|
||||||
|
continue
|
||||||
|
|
||||||
|
# TODO: use set
|
||||||
|
if option_alias not in action_info['option_names']:
|
||||||
|
action_info['option_names'].append(option_alias)
|
||||||
|
|
||||||
|
if action_doc in action_info['options']:
|
||||||
|
continue
|
||||||
|
|
||||||
|
uncommon_options.append(action_doc)
|
||||||
|
|
||||||
|
action_info['options'] = uncommon_options
|
||||||
|
|
||||||
|
docs['actions'][action] = action_info
|
||||||
|
|
||||||
docs['options'] = opt_doc_list(cli)
|
docs['options'] = opt_doc_list(cli)
|
||||||
|
|
||||||
return docs
|
return docs
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
|
||||||
template_file = 'man.j2'
|
parser = generate_parser()
|
||||||
|
|
||||||
|
options, args = parser.parse_args()
|
||||||
|
|
||||||
|
template_file = options.template_file
|
||||||
|
template_path = os.path.expanduser(template_file)
|
||||||
|
template_dir = os.path.abspath(os.path.dirname(template_path))
|
||||||
|
template_basename = os.path.basename(template_file)
|
||||||
|
|
||||||
|
output_dir = os.path.abspath(options.output_dir)
|
||||||
|
output_format = options.output_format
|
||||||
|
|
||||||
|
cli_modules = args
|
||||||
|
|
||||||
|
# various cli parsing things checks sys.argv if the 'args' that are passed in are []
|
||||||
|
# so just remove any args so the cli modules dont try to parse them resulting in warnings
|
||||||
|
sys.argv = [sys.argv[0]]
|
||||||
# need to be in right dir
|
# need to be in right dir
|
||||||
os.chdir(os.path.dirname(__file__))
|
os.chdir(os.path.dirname(__file__))
|
||||||
|
|
||||||
allvars = {}
|
allvars = {}
|
||||||
output = {}
|
output = {}
|
||||||
cli_list = []
|
cli_list = []
|
||||||
for binary in os.listdir('../../lib/ansible/cli'):
|
cli_bin_name_list = []
|
||||||
|
|
||||||
|
# for binary in os.listdir('../../lib/ansible/cli'):
|
||||||
|
for cli_module_name in cli_modules:
|
||||||
|
binary = os.path.basename(os.path.expanduser(cli_module_name))
|
||||||
|
|
||||||
if not binary.endswith('.py'):
|
if not binary.endswith('.py'):
|
||||||
continue
|
continue
|
||||||
elif binary == '__init__.py':
|
elif binary == '__init__.py':
|
||||||
continue
|
continue
|
||||||
|
|
||||||
libname = os.path.splitext(binary)[0]
|
cli_name = os.path.splitext(binary)[0]
|
||||||
print("Found CLI %s" % libname)
|
|
||||||
|
|
||||||
if libname == 'adhoc':
|
if cli_name == 'adhoc':
|
||||||
myclass = 'AdHocCLI'
|
cli_class_name = 'AdHocCLI'
|
||||||
output[libname] = 'ansible.1.asciidoc.in'
|
# myclass = 'AdHocCLI'
|
||||||
|
output[cli_name] = 'ansible.1.asciidoc.in'
|
||||||
|
cli_bin_name = 'ansible'
|
||||||
else:
|
else:
|
||||||
myclass = "%sCLI" % libname.capitalize()
|
# myclass = "%sCLI" % libname.capitalize()
|
||||||
output[libname] = 'ansible-%s.1.asciidoc.in' % libname
|
cli_class_name = "%sCLI" % cli_name.capitalize()
|
||||||
|
output[cli_name] = 'ansible-%s.1.asciidoc.in' % cli_name
|
||||||
|
cli_bin_name = 'ansible-%s' % cli_name
|
||||||
|
|
||||||
# instantiate each cli and ask its options
|
# FIXME:
|
||||||
mycli = getattr(__import__("ansible.cli.%s" % libname, fromlist=[myclass]), myclass)
|
allvars[cli_name] = opts_docs(cli_class_name, cli_name)
|
||||||
cli_object = mycli([])
|
cli_bin_name_list.append(cli_bin_name)
|
||||||
try:
|
|
||||||
cli_object.parse()
|
|
||||||
except:
|
|
||||||
# no options passed, we expect errors
|
|
||||||
pass
|
|
||||||
|
|
||||||
allvars[libname] = opts_docs(cli_object, libname)
|
|
||||||
|
|
||||||
for extras in ('ARGUMENTS'):
|
|
||||||
if hasattr(cli_object, extras):
|
|
||||||
allvars[libname][extras.lower()] = getattr(cli_object, extras)
|
|
||||||
|
|
||||||
cli_list = allvars.keys()
|
cli_list = allvars.keys()
|
||||||
for libname in cli_list:
|
|
||||||
|
doc_name_formats = {'man': '%s.1.asciidoc.in',
|
||||||
|
'rst': '%s.rst'}
|
||||||
|
|
||||||
|
for cli_name in cli_list:
|
||||||
|
|
||||||
# template it!
|
# template it!
|
||||||
env = Environment(loader=FileSystemLoader('../templates'))
|
env = Environment(loader=FileSystemLoader(template_dir))
|
||||||
template = env.get_template('man.j2')
|
template = env.get_template(template_basename)
|
||||||
|
|
||||||
# add rest to vars
|
# add rest to vars
|
||||||
tvars = allvars[libname]
|
tvars = allvars[cli_name]
|
||||||
tvars['cli_list'] = cli_list
|
tvars['cli_list'] = cli_list
|
||||||
tvars['cli'] = libname
|
tvars['cli_bin_name_list'] = cli_bin_name_list
|
||||||
|
tvars['cli'] = cli_name
|
||||||
if '-i' in tvars['options']:
|
if '-i' in tvars['options']:
|
||||||
print('uses inventory')
|
print('uses inventory')
|
||||||
|
|
||||||
manpage = template.render(tvars)
|
manpage = template.render(tvars)
|
||||||
filename = '../man/man1/%s' % output[libname]
|
filename = os.path.join(output_dir, doc_name_formats[output_format] % tvars['cli_name'])
|
||||||
|
|
||||||
with open(filename, 'wb') as f:
|
with open(filename, 'wb') as f:
|
||||||
f.write(to_bytes(manpage))
|
f.write(to_bytes(manpage))
|
||||||
print("Wrote man docs to %s" % filename)
|
print("Wrote doc to %s" % filename)
|
||||||
|
|
|
@ -4,6 +4,7 @@ FORMATTER=../bin/plugin_formatter.py
|
||||||
TESTING_FORMATTER=../bin/testing_formatter.sh
|
TESTING_FORMATTER=../bin/testing_formatter.sh
|
||||||
DUMPER=../bin/dump_keywords.py
|
DUMPER=../bin/dump_keywords.py
|
||||||
CONFIG_DUMPER=../bin/dump_config.py
|
CONFIG_DUMPER=../bin/dump_config.py
|
||||||
|
GENERATE_CLI=../bin/generate_man.py
|
||||||
ifeq ($(shell echo $(OS) | egrep -ic 'Darwin|FreeBSD|OpenBSD|DragonFly'),1)
|
ifeq ($(shell echo $(OS) | egrep -ic 'Darwin|FreeBSD|OpenBSD|DragonFly'),1)
|
||||||
CPUS ?= $(shell sysctl hw.ncpu|awk '{print $$2}')
|
CPUS ?= $(shell sysctl hw.ncpu|awk '{print $$2}')
|
||||||
else
|
else
|
||||||
|
@ -19,7 +20,8 @@ all: docs
|
||||||
|
|
||||||
docs: clean htmldocs
|
docs: clean htmldocs
|
||||||
|
|
||||||
htmldocs: testing keywords modules staticmin config
|
htmldocs: testing keywords modules staticmin cli config
|
||||||
|
|
||||||
CPUS=$(CPUS) $(MAKE) -f Makefile.sphinx html
|
CPUS=$(CPUS) $(MAKE) -f Makefile.sphinx html
|
||||||
|
|
||||||
webdocs: docs
|
webdocs: docs
|
||||||
|
@ -45,9 +47,14 @@ clean:
|
||||||
-rm rst/*_maintained.rst
|
-rm rst/*_maintained.rst
|
||||||
-rm rst/playbooks_directives.rst
|
-rm rst/playbooks_directives.rst
|
||||||
-rm rst/playbooks_keywords.rst
|
-rm rst/playbooks_keywords.rst
|
||||||
|
# -rm rst/cli/ansible*.rst
|
||||||
|
|
||||||
.PHONEY: docs clean
|
.PHONEY: docs clean
|
||||||
|
|
||||||
|
# TODO: make generate_man output dir cli option
|
||||||
|
cli: $(GENERATE_CLI)
|
||||||
|
PYTHONPATH=../../lib $(GENERATE_CLI) --template-file=../templates/cli_rst.j2 --output-dir=rst/ --output-format rst ../../lib/ansible/cli/*.py
|
||||||
|
|
||||||
keywords: $(FORMATTER) ../templates/playbooks_keywords.rst.j2
|
keywords: $(FORMATTER) ../templates/playbooks_keywords.rst.j2
|
||||||
PYTHONPATH=../../lib $(DUMPER) --template-dir=../templates --output-dir=rst/ -d ./keyword_desc.yml
|
PYTHONPATH=../../lib $(DUMPER) --template-dir=../templates --output-dir=rst/ -d ./keyword_desc.yml
|
||||||
|
|
||||||
|
|
15
docs/docsite/rst/command_line_tools.rst
Normal file
15
docs/docsite/rst/command_line_tools.rst
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
Command Line Tools
|
||||||
|
==================
|
||||||
|
|
||||||
|
|
||||||
|
.. toctree:: :maxdepth: 1
|
||||||
|
|
||||||
|
ansible
|
||||||
|
ansible-playbook
|
||||||
|
ansible-vault
|
||||||
|
ansible-galaxy
|
||||||
|
ansible-console
|
||||||
|
ansible-config
|
||||||
|
ansible-doc
|
||||||
|
ansible-inventory
|
||||||
|
ansible-pull
|
|
@ -32,6 +32,7 @@ Ansible, Inc. releases a new major release of Ansible approximately every two mo
|
||||||
modules
|
modules
|
||||||
modules_by_category
|
modules_by_category
|
||||||
vault
|
vault
|
||||||
|
command_line_tools
|
||||||
guides
|
guides
|
||||||
dev_guide/index
|
dev_guide/index
|
||||||
tower
|
tower
|
||||||
|
|
|
@ -5,7 +5,7 @@ Ansible Vault
|
||||||
|
|
||||||
New in Ansible 1.5, "Vault" is a feature of ansible that allows keeping sensitive data such as passwords or keys in encrypted files, rather than as plaintext in your playbooks or roles. These vault files can then be distributed or placed in source control.
|
New in Ansible 1.5, "Vault" is a feature of ansible that allows keeping sensitive data such as passwords or keys in encrypted files, rather than as plaintext in your playbooks or roles. These vault files can then be distributed or placed in source control.
|
||||||
|
|
||||||
To enable this feature, a command line tool, :ref:`ansible-vault` is used to edit files, and a command line flag `--ask-vault-pass` or `--vault-password-file` is used. Alternately, you may specify the location of a password file or command Ansible to always prompt for the password in your ansible.cfg file. These options require no command line flag usage.
|
To enable this feature, a command line tool - :ref:`ansible-vault` - is used to edit files, and a command line flag (:option:`--ask-vault-pass <ansible-playbook --ask-vault-pass>` or :option:`--vault-password-file <ansible-playbook --vault-password-file>`) is used. Alternately, you may specify the location of a password file or command Ansible to always prompt for the password in your ansible.cfg file. These options require no command line flag usage.
|
||||||
|
|
||||||
For best practices advice, refer to :ref:`best_practices_for_variables_and_vaults`.
|
For best practices advice, refer to :ref:`best_practices_for_variables_and_vaults`.
|
||||||
|
|
||||||
|
@ -48,7 +48,7 @@ The default cipher is AES (which is shared-secret based).
|
||||||
Editing Encrypted Files
|
Editing Encrypted Files
|
||||||
```````````````````````
|
```````````````````````
|
||||||
|
|
||||||
To edit an encrypted file in place, use the :ref:`ansible-vault edit` command.
|
To edit an encrypted file in place, use the :ref:`ansible-vault edit <ansible_vault_edit>` command.
|
||||||
This command will decrypt the file to a temporary file and allow you to edit
|
This command will decrypt the file to a temporary file and allow you to edit
|
||||||
the file, saving it back when done and removing the temporary file:
|
the file, saving it back when done and removing the temporary file:
|
||||||
|
|
||||||
|
@ -78,7 +78,7 @@ Encrypting Unencrypted Files
|
||||||
````````````````````````````
|
````````````````````````````
|
||||||
|
|
||||||
If you have existing files that you wish to encrypt, use
|
If you have existing files that you wish to encrypt, use
|
||||||
the :ref:`ansible-vault encrypt` command. This command can operate on multiple files at once:
|
the :ref:`ansible-vault encrypt <ansible_vault_encrypt>` command. This command can operate on multiple files at once:
|
||||||
|
|
||||||
.. code-block:: bash
|
.. code-block:: bash
|
||||||
|
|
||||||
|
@ -91,8 +91,8 @@ Decrypting Encrypted Files
|
||||||
``````````````````````````
|
``````````````````````````
|
||||||
|
|
||||||
If you have existing files that you no longer want to keep encrypted, you can permanently decrypt
|
If you have existing files that you no longer want to keep encrypted, you can permanently decrypt
|
||||||
them by running the :ref:`ansible-vault decrypt` command. This command will save them unencrypted
|
them by running the :ref:`ansible-vault decrypt <ansible_vault_decrypt>` command. This command will save them unencrypted
|
||||||
to the disk, so be sure you do not want :ref:`ansible-vault edit` instead:
|
to the disk, so be sure you do not want :ref:`ansible-vault edit <ansible_vault_edit>` instead:
|
||||||
|
|
||||||
.. code-block:: bash
|
.. code-block:: bash
|
||||||
|
|
||||||
|
@ -106,7 +106,7 @@ Viewing Encrypted Files
|
||||||
|
|
||||||
*Available since Ansible 1.8*
|
*Available since Ansible 1.8*
|
||||||
|
|
||||||
If you want to view the contents of an encrypted file without editing it, you can use the :ref:`ansible-vault view` command:
|
If you want to view the contents of an encrypted file without editing it, you can use the :ref:`ansible-vault view <ansible_vault_view>` command:
|
||||||
|
|
||||||
.. code-block:: bash
|
.. code-block:: bash
|
||||||
|
|
||||||
|
@ -118,10 +118,11 @@ If you want to view the contents of an encrypted file without editing it, you ca
|
||||||
Use encrypt_string to create encrypted variables to embed in yaml
|
Use encrypt_string to create encrypted variables to embed in yaml
|
||||||
`````````````````````````````````````````````````````````````````
|
`````````````````````````````````````````````````````````````````
|
||||||
|
|
||||||
The :ref:`ansible-vault encrypt_string` command will encrypt and format a provided string into a format
|
The :ref:`ansible-vault encrypt_string <ansible_vault_encrypt_string>` command will encrypt and format a provided string into a format
|
||||||
that can be included in :ref:`ansible-playbook` YAML files.
|
that can be included in :ref:`ansible-playbook` YAML files.
|
||||||
|
|
||||||
To encrypt a string provided as a cli arg:
|
To encrypt a string provided as a cli arg:
|
||||||
|
|
||||||
.. code-block:: bash
|
.. code-block:: bash
|
||||||
|
|
||||||
ansible-vault encrypt_string --vault-id a_password_file 'foobar' --name 'the_secret'
|
ansible-vault encrypt_string --vault-id a_password_file 'foobar' --name 'the_secret'
|
||||||
|
@ -224,7 +225,7 @@ Providing Vault Passwords
|
||||||
`````````````````````````
|
`````````````````````````
|
||||||
|
|
||||||
Since Ansible 2.4, the recommended way to provide a vault password from the cli is
|
Since Ansible 2.4, the recommended way to provide a vault password from the cli is
|
||||||
to use the :option:`--vault-id` cli option.
|
to use the :option:`--vault-id <ansible-playbook --vault-id>` cli option.
|
||||||
|
|
||||||
For example, to use a password store in the text file :file:`/path/to/my/vault-password-file`:
|
For example, to use a password store in the text file :file:`/path/to/my/vault-password-file`:
|
||||||
|
|
||||||
|
@ -244,7 +245,7 @@ To get the password from a vault password executable script :file:`my-vault-pass
|
||||||
|
|
||||||
ansible-playbook --vault-id my-vault-password.py
|
ansible-playbook --vault-id my-vault-password.py
|
||||||
|
|
||||||
The value for :option:`--vault-id` can specify the type of vault id (prompt, a file path, etc)
|
The value for :option:`--vault-id <ansible-playbook --vault-id>` can specify the type of vault id (prompt, a file path, etc)
|
||||||
and a label for the vault id ('dev', 'prod', 'cloud', etc)
|
and a label for the vault id ('dev', 'prod', 'cloud', etc)
|
||||||
|
|
||||||
For example, to use a password file :file:`dev-password` for the vault-id 'dev':
|
For example, to use a password file :file:`dev-password` for the vault-id 'dev':
|
||||||
|
@ -261,20 +262,20 @@ To prompt for the 'dev' vault id:
|
||||||
|
|
||||||
*Prior to Ansible 2.4*
|
*Prior to Ansible 2.4*
|
||||||
|
|
||||||
To be prompted for a vault password, use the :option:`--ask-vault-pass` cli option:
|
To be prompted for a vault password, use the :option:`--ask-vault-pass <ansible-playbook --vault-id>` cli option:
|
||||||
|
|
||||||
.. code-block:: bash
|
.. code-block:: bash
|
||||||
|
|
||||||
ansible-playbook --ask-vault-pass site.yml
|
ansible-playbook --ask-vault-pass site.yml
|
||||||
|
|
||||||
To specify a vault password in a text file 'dev-password', use the :option:`--vault-password-file` option:
|
To specify a vault password in a text file 'dev-password', use the :option:`--vault-password-file <ansible-playbook --vault-password-file>` option:
|
||||||
|
|
||||||
.. code-block:: bash
|
.. code-block:: bash
|
||||||
|
|
||||||
ansible-playbook --vault-password-file dev-password site.yml
|
ansible-playbook --vault-password-file dev-password site.yml
|
||||||
|
|
||||||
There is a config option (:ref:`DEFAULT_VAULT_PASSWORD_FILE`) to specify a vault password file to use
|
There is a config option (:ref:`DEFAULT_VAULT_PASSWORD_FILE`) to specify a vault password file to use
|
||||||
without requiring the :option:`--vault-password-file` cli option.
|
without requiring the :option:`--vault-password-file <ansible-playbook --vault-password-file>` cli option.
|
||||||
|
|
||||||
via config
|
via config
|
||||||
:ref:`ANSIBLE_VAULT_PASSWORD_FILE`
|
:ref:`ANSIBLE_VAULT_PASSWORD_FILE`
|
||||||
|
@ -287,7 +288,7 @@ via env
|
||||||
Multiple vault passwords
|
Multiple vault passwords
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
Since Ansible 2.4 and later support using multiple vault passwords, :option:`--vault-id` can
|
Since Ansible 2.4 and later support using multiple vault passwords, :option:`--vault-id <ansible-playbook --vault-id>` can
|
||||||
be provided multiple times.
|
be provided multiple times.
|
||||||
|
|
||||||
If multiple vault passwords are provided, by default Ansible will attempt to decrypt vault content
|
If multiple vault passwords are provided, by default Ansible will attempt to decrypt vault content
|
||||||
|
@ -302,7 +303,7 @@ For example, to use a 'dev' password read from a file and to be prompted for the
|
||||||
In the above case, the 'dev' password will be tried first, then the 'prod' password for cases
|
In the above case, the 'dev' password will be tried first, then the 'prod' password for cases
|
||||||
where Ansible doesn't know which vault id is used to encrypt something.
|
where Ansible doesn't know which vault id is used to encrypt something.
|
||||||
|
|
||||||
If the vault content was encrypted using a :option:`--vault-id` option, then the label of the
|
If the vault content was encrypted using a :option:`--vault-id <ansible-vault --vault-id>` option, then the label of the
|
||||||
vault id is stored with the vault content. When Ansible knows the right vault-id, it will try
|
vault id is stored with the vault content. When Ansible knows the right vault-id, it will try
|
||||||
the matching vault id's secret first before trying the rest of the vault-ids.
|
the matching vault id's secret first before trying the rest of the vault-ids.
|
||||||
|
|
||||||
|
@ -317,17 +318,17 @@ use. For example, instead of requiring the cli option on every use, the (:ref:`D
|
||||||
|
|
||||||
ansible-playbook --vault-id dev@dev-password --vault-id prod@prompt site.yml
|
ansible-playbook --vault-id dev@dev-password --vault-id prod@prompt site.yml
|
||||||
|
|
||||||
The :option:`--vault-id` can be used in lieu of the :option:`--vault-password-file` or :option:`--ask-vault-pass` options,
|
The :option:`--vault-id <ansible-playbook --vault-id>` can be used in lieu of the :option:`--vault-password-file <ansible-playbook --vault-password-file>` or :option:`--ask-vault-pass <ansible-playbook --ask-vault-pass>` options,
|
||||||
or it can be used in combination with them.
|
or it can be used in combination with them.
|
||||||
|
|
||||||
When using :ref:`ansible-vault` command that encrypt content (:ref:`ansible-vault encrypt`, :ref:`ansible-vault encrypt_string`, etc)
|
When using :ref:`ansible-vault` commands that encrypt content (:ref:`ansible-vault encrypt <ansible_vault_encrypt>`, :ref:`ansible-vault encrypt_string <ansible_vault_encrypt_string>`, etc)
|
||||||
only one vault-id can be used.
|
only one vault-id can be used.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
Prior to Ansible 2.4, only one vault password could be used in each Ansible run. The
|
Prior to Ansible 2.4, only one vault password could be used in each Ansible run. The
|
||||||
:option:`--vault-id` option is not support prior to Ansible 2.4.
|
:option:`--vault-id <ansible-playbook --vault-id>` option is not support prior to Ansible 2.4.
|
||||||
|
|
||||||
|
|
||||||
.. _speeding_up_vault:
|
.. _speeding_up_vault:
|
||||||
|
|
139
docs/templates/cli_rst.j2
vendored
Normal file
139
docs/templates/cli_rst.j2
vendored
Normal file
|
@ -0,0 +1,139 @@
|
||||||
|
{% set name = cli_name -%}
|
||||||
|
{% set name_slug = cli_name -%}
|
||||||
|
|
||||||
|
.. _{{name}}:
|
||||||
|
|
||||||
|
{% set name_len = name|length + 0-%}
|
||||||
|
{{ '=' * name_len }}
|
||||||
|
{{name}}
|
||||||
|
{{ '=' * name_len }}
|
||||||
|
|
||||||
|
|
||||||
|
:strong:`{{short_desc|default('')}}`
|
||||||
|
|
||||||
|
|
||||||
|
.. contents::
|
||||||
|
:local:
|
||||||
|
:depth: 2
|
||||||
|
|
||||||
|
|
||||||
|
.. program:: {{cli_name}}
|
||||||
|
|
||||||
|
Synopsis
|
||||||
|
========
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
{{ usage|replace('%prog', cli_name) }}
|
||||||
|
|
||||||
|
|
||||||
|
Description
|
||||||
|
===========
|
||||||
|
|
||||||
|
|
||||||
|
{{ long_desc|default('', True) }}
|
||||||
|
|
||||||
|
{% if options %}
|
||||||
|
Common Options
|
||||||
|
==============
|
||||||
|
|
||||||
|
|
||||||
|
{% for option in options|sort(attribute='options') %}
|
||||||
|
|
||||||
|
.. option:: {% for switch in option['options'] %}{{switch}}{% if option['arg'] %} <{{option['arg']}}>{% endif %}{% if not loop.last %}, {% endif %}{% endfor %}
|
||||||
|
|
||||||
|
{{ option['desc'] }}
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if arguments %}
|
||||||
|
ARGUMENTS
|
||||||
|
=========
|
||||||
|
|
||||||
|
.. program:: {{cli_name}}
|
||||||
|
|
||||||
|
{% for arg in arguments %}
|
||||||
|
.. option:: {{ arg }}
|
||||||
|
|
||||||
|
{{ (arguments[arg]|default(' '))}}
|
||||||
|
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if actions %}
|
||||||
|
Actions
|
||||||
|
=======
|
||||||
|
|
||||||
|
{% for action in actions %}
|
||||||
|
|
||||||
|
.. program:: {{cli_name}} {{action}}
|
||||||
|
.. _{{cli_name|replace('-','_')}}_{{action}}:
|
||||||
|
|
||||||
|
{{ action}}
|
||||||
|
{{ '-' * action|length}}
|
||||||
|
|
||||||
|
{{ (actions[action]['desc']|default(' '))}}
|
||||||
|
|
||||||
|
{% if actions[action]['options'] %}
|
||||||
|
|
||||||
|
|
||||||
|
{% for option in actions[action]['options']|sort %}
|
||||||
|
.. option:: {% for switch in option['options'] if switch in actions[action]['option_names'] %}{{switch}} {% if option['arg'] %} <{{option['arg']}}>{% endif %}{% if not loop.last %}, {% endif %}{% endfor %}
|
||||||
|
|
||||||
|
{{ (option['desc']) }}
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% endfor %}
|
||||||
|
.. program:: {{cli_name}}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
Environment
|
||||||
|
===========
|
||||||
|
|
||||||
|
The following environment variables may be specified.
|
||||||
|
|
||||||
|
{% if inventory %}
|
||||||
|
:envvar:`ANSIBLE_INVENTORY` -- Override the default ansible inventory file
|
||||||
|
|
||||||
|
{% endif %}
|
||||||
|
{% if library %}
|
||||||
|
:envvar:`ANSIBLE_LIBRARY` -- Override the default ansible module library path
|
||||||
|
|
||||||
|
{% endif %}
|
||||||
|
:envvar:`ANSIBLE_CONFIG` -- Override the default ansible config file
|
||||||
|
|
||||||
|
Many more are available for most options in ansible.cfg
|
||||||
|
|
||||||
|
|
||||||
|
Files
|
||||||
|
=====
|
||||||
|
|
||||||
|
{% if inventory %}
|
||||||
|
:file:`/etc/ansible/hosts` -- Default inventory file
|
||||||
|
|
||||||
|
{% endif %}
|
||||||
|
:file:`/etc/ansible/ansible.cfg` -- Config file, used if present
|
||||||
|
|
||||||
|
:file:`~/.ansible.cfg` -- User config file, overrides the default config if present
|
||||||
|
|
||||||
|
Author
|
||||||
|
======
|
||||||
|
|
||||||
|
Ansible was originally written by Michael DeHaan.
|
||||||
|
|
||||||
|
See the `AUTHORS` file for a complete list of contributors.
|
||||||
|
|
||||||
|
|
||||||
|
Copyright
|
||||||
|
=========
|
||||||
|
|
||||||
|
Copyright © 2017 Red Hat, Inc | Ansible.
|
||||||
|
|
||||||
|
Ansible is released under the terms of the GPLv3 License.
|
||||||
|
|
||||||
|
See also
|
||||||
|
========
|
||||||
|
|
||||||
|
{% for other in cli_bin_name_list|sort %}:manpage:`{{other}}(1)`, {% endfor %}
|
||||||
|
|
30
docs/templates/man.j2
vendored
30
docs/templates/man.j2
vendored
|
@ -20,8 +20,17 @@ SYNOPSIS
|
||||||
|
|
||||||
DESCRIPTION
|
DESCRIPTION
|
||||||
-----------
|
-----------
|
||||||
*{{name}}* {{ long_desc|default('', True)|wordwrap }}
|
{{ long_desc|default('', True)|wordwrap }}
|
||||||
|
|
||||||
|
{% if options %}
|
||||||
|
COMMON OPTIONS
|
||||||
|
--------------
|
||||||
|
{% for option in options|sort(attribute='options') %}
|
||||||
|
{% for switch in option['options'] %}*{{switch}}*{% if option['arg'] %} '{{option['arg']}}'{% endif %}{% if not loop.last %}, {% endif %}{% endfor %}::
|
||||||
|
|
||||||
|
{{ option['desc'] }}
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
{% if arguments %}
|
{% if arguments %}
|
||||||
ARGUMENTS
|
ARGUMENTS
|
||||||
|
@ -38,22 +47,19 @@ ARGUMENTS
|
||||||
{% if actions %}
|
{% if actions %}
|
||||||
ACTIONS
|
ACTIONS
|
||||||
-------
|
-------
|
||||||
|
|
||||||
{% for action in actions %}
|
{% for action in actions %}
|
||||||
{{ action }}
|
*{{ action }}*::: {{ (actions[action]['desc']|default(' '))|wordwrap}}
|
||||||
|
|
||||||
{{ (actions[action]|default(' '))|wordwrap}}
|
{% if actions[action]['options'] %}
|
||||||
|
{% for option in actions[action]['options']|sort %}
|
||||||
|
{% for switch in option['options'] if switch in actions[action]['option_names'] %}*{{switch}}*{% if option['arg'] %} '{{option['arg']}}'{% endif %}{% if not loop.last %}, {% endif %}{% endfor %}::
|
||||||
|
|
||||||
|
{{ (option['desc']) }}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
OPTIONS
|
|
||||||
-------
|
|
||||||
|
|
||||||
{% for option in options|sort(attribute='options') %}
|
|
||||||
{% for switch in option['options'] %}*{{switch}}* {% if option['arg'] %}'{{option['arg']}}'{% endif %}{% if not loop.last %}, {% endif %}{% endfor %}::
|
|
||||||
|
|
||||||
{{ option['desc'] }}
|
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
|
||||||
{% if inventory %}
|
{% if inventory %}
|
||||||
INVENTORY
|
INVENTORY
|
||||||
|
@ -111,7 +117,7 @@ Ansible is released under the terms of the GPLv3 License.
|
||||||
SEE ALSO
|
SEE ALSO
|
||||||
--------
|
--------
|
||||||
|
|
||||||
{% for other in cli_list|sort %}{% if other != cli %}*ansible{% if other != 'adhoc' %}-{{other}}{% endif %}*(1){% if not loop.last %}, {% endif %}{% endif %}{% endfor %}
|
{% for other in cli_list|sort %}{% if other != cli %}*ansible{% if other != 'adhoc' %}-{{other}}{% endif %}*(1){% if not loop.last %}, {% endif %}{% endif %}{% endfor %}
|
||||||
|
|
||||||
Extensive documentation is available in the documentation site:
|
Extensive documentation is available in the documentation site:
|
||||||
<http://docs.ansible.com>.
|
<http://docs.ansible.com>.
|
||||||
|
|
|
@ -56,7 +56,8 @@ class ConfigCLI(CLI):
|
||||||
|
|
||||||
self.parser = CLI.base_parser(
|
self.parser = CLI.base_parser(
|
||||||
usage = "usage: %%prog [%s] [--help] [options] [ansible.cfg]" % "|".join(self.VALID_ACTIONS),
|
usage = "usage: %%prog [%s] [--help] [options] [ansible.cfg]" % "|".join(self.VALID_ACTIONS),
|
||||||
epilog = "\nSee '%s <command> --help' for more information on a specific command.\n\n" % os.path.basename(sys.argv[0])
|
epilog = "\nSee '%s <command> --help' for more information on a specific command.\n\n" % os.path.basename(sys.argv[0]),
|
||||||
|
desc="View, edit, and manage ansible configuration.",
|
||||||
)
|
)
|
||||||
|
|
||||||
self.parser.add_option('-c', '--config', dest='config_file', help="path to configuration file, defaults to first file found in precedence.")
|
self.parser.add_option('-c', '--config', dest='config_file', help="path to configuration file, defaults to first file found in precedence.")
|
||||||
|
|
Loading…
Reference in a new issue