2016-06-15 21:01:55 +00:00
|
|
|
#!/usr/bin/env python
|
2016-02-25 21:41:50 +00:00
|
|
|
|
|
|
|
import optparse
|
2017-11-11 00:59:26 +00:00
|
|
|
import re
|
|
|
|
from distutils.version import LooseVersion
|
2017-03-15 15:29:58 +00:00
|
|
|
|
2017-11-11 00:59:26 +00:00
|
|
|
import jinja2
|
|
|
|
import yaml
|
2016-02-25 21:41:50 +00:00
|
|
|
from jinja2 import Environment, FileSystemLoader
|
|
|
|
|
2017-01-27 23:45:23 +00:00
|
|
|
from ansible.playbook import Play
|
|
|
|
from ansible.playbook.block import Block
|
|
|
|
from ansible.playbook.role import Role
|
|
|
|
from ansible.playbook.task import Task
|
2016-02-25 21:41:50 +00:00
|
|
|
|
2017-03-23 05:13:23 +00:00
|
|
|
template_file = 'playbooks_keywords.rst.j2'
|
2016-02-25 21:41:50 +00:00
|
|
|
oblist = {}
|
2016-02-26 21:18:55 +00:00
|
|
|
clist = []
|
2017-05-30 17:08:25 +00:00
|
|
|
class_list = [Play, Role, Block, Task]
|
2016-02-25 21:41:50 +00:00
|
|
|
|
|
|
|
p = optparse.OptionParser(
|
|
|
|
version='%prog 1.0',
|
|
|
|
usage='usage: %prog [options]',
|
2017-11-11 00:59:26 +00:00
|
|
|
description='Generate playbook keyword documentation from code and descriptions',
|
2016-02-25 21:41:50 +00:00
|
|
|
)
|
2017-03-23 05:13:23 +00:00
|
|
|
p.add_option("-T", "--template-dir", action="store", dest="template_dir", default="../templates", help="directory containing Jinja2 templates")
|
2016-02-25 21:41:50 +00:00
|
|
|
p.add_option("-o", "--output-dir", action="store", dest="output_dir", default='/tmp/', help="Output directory for rst files")
|
2017-03-15 15:29:58 +00:00
|
|
|
p.add_option("-d", "--docs-source", action="store", dest="docs", default=None, help="Source for attribute docs")
|
2016-02-25 21:41:50 +00:00
|
|
|
|
|
|
|
(options, args) = p.parse_args()
|
|
|
|
|
2016-02-26 21:27:10 +00:00
|
|
|
for aclass in class_list:
|
2016-02-26 21:18:55 +00:00
|
|
|
aobj = aclass()
|
|
|
|
name = type(aobj).__name__
|
|
|
|
|
2017-03-15 15:29:58 +00:00
|
|
|
if options.docs:
|
|
|
|
with open(options.docs) as f:
|
|
|
|
docs = yaml.safe_load(f)
|
|
|
|
else:
|
|
|
|
docs = {}
|
|
|
|
|
2016-02-26 21:18:55 +00:00
|
|
|
# build ordered list to loop over and dict with attributes
|
|
|
|
clist.append(name)
|
2017-01-27 21:04:59 +00:00
|
|
|
oblist[name] = dict((x, aobj.__dict__['_attributes'][x]) for x in aobj.__dict__['_attributes'] if 'private' not in x or not x.private)
|
2016-02-26 21:18:55 +00:00
|
|
|
|
2017-03-15 15:29:58 +00:00
|
|
|
# pick up docs if they exist
|
|
|
|
for a in oblist[name]:
|
|
|
|
if a in docs:
|
|
|
|
oblist[name][a] = docs[a]
|
|
|
|
else:
|
|
|
|
oblist[name][a] = ' UNDOCUMENTED!! '
|
|
|
|
|
2016-02-26 21:18:55 +00:00
|
|
|
# loop is really with_ for users
|
2016-03-10 06:00:33 +00:00
|
|
|
if name == 'Task':
|
2017-12-20 15:20:05 +00:00
|
|
|
oblist[name]['with_<lookup_plugin>'] = 'DEPRECATED: use ``loop`` instead, ``with_`` used to be how loops were defined, '
|
move from with_<lookup>: to loop:
- old functionality is still available direct lookup use, the following are equivalent
with_nested: [[1,2,3], ['a','b','c']]
loop: "{{lookup('nested', [1,2,3], ['a','b','c'])}}"
- avoid squashing with 'loop:'
- fixed test to use new intenal attributes
- removed most of 'lookup docs' as these now reside in the plugins
2017-09-17 03:32:34 +00:00
|
|
|
'it can use any available lookup plugin to generate the item list'
|
2016-02-26 21:18:55 +00:00
|
|
|
|
|
|
|
# local_action is implicit with action
|
|
|
|
if 'action' in oblist[name]:
|
2017-03-20 19:47:15 +00:00
|
|
|
oblist[name]['local_action'] = 'Same as action but also implies ``delegate_to: localhost``'
|
|
|
|
|
|
|
|
# remove unusable (used to be private?)
|
move from with_<lookup>: to loop:
- old functionality is still available direct lookup use, the following are equivalent
with_nested: [[1,2,3], ['a','b','c']]
loop: "{{lookup('nested', [1,2,3], ['a','b','c'])}}"
- avoid squashing with 'loop:'
- fixed test to use new intenal attributes
- removed most of 'lookup docs' as these now reside in the plugins
2017-09-17 03:32:34 +00:00
|
|
|
for nouse in ('loop_args'):
|
2017-03-20 19:47:15 +00:00
|
|
|
if nouse in oblist[name]:
|
|
|
|
del oblist[name][nouse]
|
2016-02-26 21:18:55 +00:00
|
|
|
|
2016-02-25 21:41:50 +00:00
|
|
|
env = Environment(loader=FileSystemLoader(options.template_dir), trim_blocks=True,)
|
|
|
|
template = env.get_template(template_file)
|
2017-05-30 17:08:25 +00:00
|
|
|
outputname = options.output_dir + template_file.replace('.j2', '')
|
|
|
|
tempvars = {'oblist': oblist, 'clist': clist}
|
2016-02-25 21:41:50 +00:00
|
|
|
|
2017-11-11 00:59:26 +00:00
|
|
|
keyword_page = template.render(tempvars)
|
|
|
|
if LooseVersion(jinja2.__version__) < LooseVersion('2.10'):
|
|
|
|
# jinja2 < 2.10's indent filter indents blank lines. Cleanup
|
|
|
|
keyword_page = re.sub(' +\n', '\n', keyword_page)
|
|
|
|
|
2017-05-30 17:08:25 +00:00
|
|
|
with open(outputname, 'w') as f:
|
2017-11-11 00:59:26 +00:00
|
|
|
f.write(keyword_page)
|