im trying to programm a new ansible module. while testing i get the following error.
Traceback (most recent call last): File "/tmp/ansible_EHl4xq/ansible_module_aix_stanza.py", line 276, in <module> main() File "/tmp/ansible_EHl4xq/ansible_module_aix_stanza.py", line 257, in main (changed, backup_file, diff, msg) = do_stanza(module, path, stanza, options, state, backup, create) TypeError: 'NoneType' object is not iterable i cannot see whats the particular problem here...any hints? #!/usr/bin/python # -*- coding: utf-8 -*- from __future__ import absolute_import, division, print_function __metaclass__ = type ANSIBLE_METADATA = { 'metadata_version': '1.1', 'status': ['preview'], 'supported_by': 'community' } DOCUMENTATION = ''' --- module: aix_stanza short_description: modify aix stanza files version_added: "0.1" description: - "adds stanza lines/addr/value pairs, changes attr/value pairs, removes stanzas/attr/value pairs" options: path: description: - Path to the stanza file required: true stanza: description: - name of add_stanza required: true options: description: - comman separated key/value pairs (key=val,key=val,...) backup: description: - Create a backup file including the timestamp information so you can get the original file back if you somehow clobbered it incorrectly. type: bool default: 'no' state: description: - If set to C(absent) the stanza will be removed if present instead of created. choices: [ absent, present ] default: present others: description: - All arguments accepted by the M(file) module also work here extends_documentation_fragment: - files author: - Christian Tremel (@flynn1973) ''' EXAMPLES = ''' - name: add ldap user stanza aix_stanza: path: /etc/security/user stanza: exampleuser options: SYSTEM=LDAP,registry=LDAP state: present mode: 0644 backup: yes - name: add filesystem entry aix_stanza: path: /etc/filesystems stanza: /examplemount options: dev=/dev/lvosystem_c,vfs=jfs2,log=INLINE,mount=true state: present backup: yes ''' import os import re import tempfile import traceback from ansible.module_utils.basic import * def match_option(option, line): option = list(options.items()) option = re.escape(option) return re.match('( |\t)*%s( |\t)*(=|$)' % option, line) \ or re.match('#( |\t)*%s( |\t)*(=|$)' % option, line) \ or re.match(';( |\t)*%s( |\t)*(=|$)' % option, line) def match_active_option(option, line): option = list(options.items()) option = re.escape(option) return re.match('( |\t)*%s( |\t)*(=|$)' % option, line) def match_stanza(stanza, line): stanza = re.escape(stanza) return re.match('^%s:[^:]*(?=[\s])' % stanza, line) def do_stanza(module, filename, stanza, options, state='present', backup= False, create=True): diff = dict( before='', after='', before_header='%s (content)' % filename, after_header='%s (content)' % filename, ) if not os.path.exists(filename): if not create: module.fail_json(rc=257, msg='Destination %s does not exist !' % filename) destpath = os.path.dirname(filename) if not os.path.exists(destpath) and not module.check_mode: os.makedirs(destpath) stanza_lines = [] else: stanza_file = open(filename, 'r') try: stanza_lines = stanza_file.readlines() finally: stanza_file.close() if module._diff: diff['before'] = ''.join(stanza_lines) changed = False # stanza file may be empty so add at least a newline if not stanza_lines: stanza_lines.append('\n') # last line should always be a newline to keep up with POSIX standard if stanza_lines[-1] == "" or stanza_lines[-1][-1] != '\n': stanza_lines[-1] += '\n' changed = True if not stanza: module.fail_json(msg="stanza name not set", rc=rc, err=err) stanza_format = '\n%s\n' option_format = '\t%s = %s\n' for index, line in enumerate(stanza_lines): if line.startswith('%s:' % stanza): within_stanza = True stanza_start = index if within_stanza: if state == 'present': # loop through options dict for opt in list(options.keys()): # insert missing option lines at the end of the section for i in range(index, 0, -1): # search backwards for previous non-blank or non-comment lines if not re.match(r'^[ \t]*([#;].*)?$', stanza_lines[i - 1]): stanza_lines.insert(i, option_format % (opt, options[opt])) msg = 'options added' changed = True break elif state == 'absent' and not options: # remove the entire stanza if no option lines present del stanza_lines[stanza_start:index] msg = 'stanza removed' changed = True break else: if within_stanza and options: if state == 'present': # loop through options dict for opt in list(options.keys()): # change existing option lines if match_option(opt, line): newline = option_format % (opt, options[opt ]) option_changed = stanza_lines[index] != newline changed = changed or option_changed if option_changed: msg = 'option changed' stanza_lines[index] = newline if option_changed: # remove all possible option occurrences from the stanza index = index + 1 while index < len(stanza_lines): line = stanza_lines[index] if match_active_option(opt, line): del stanza_lines[index] else: index = index + 1 break elif state == 'absent': # delete the existing line if match_active_option(opt, line): del stanza_lines[index] changed = True msg = 'option removed' break if not within_stanza and option and state == 'present': stanza_lines.append(stanza_format % stanza) # loop through options dict for opt in list(options.keys()): stanza_lines.append(option_format % (opt, options[opt])) changed = True msg = 'stanza and option added' if module._diff: diff['after'] = ''.join(stanza_lines) backup_file = None if changed and not module.check_mode: if backup: backup_file = module.backup_local(filename) try: tmpfd, tmpfile = tempfile.mkstemp(dir=module.tmpdir) f = os.fdopen(tmpfd, 'w') f.writelines(stanza_lines) f.close() except IOError: module.fail_json(msg="Unable to create temporary file %s", traceback=traceback.format_exc()) try: module.atomic_move(tmpfile, filename) except IOError: module.ansible.fail_json(msg='Unable to move temporary file %s to %s, IOError' % (tmpfile, filename), traceback=traceback. format_exc()) return (changed, backup_file, diff, msg) def main(): module = AnsibleModule( argument_spec=dict( path=dict(type='path', required=True, aliases=['dest']), stanza=dict(type='str', required=True), options=dict(type='dict', required=True), backup=dict(type='bool', default=False), state=dict(type='str', default='present', choices=['absent', 'present']), create=dict(type='bool', default=True) ), add_file_common_args=True, supports_check_mode=True, ) path = module.params['path'] stanza = module.params['stanza'] options = module.params['options'] state = module.params['state'] backup = module.params['backup'] create = module.params['create'] (changed, backup_file, diff, msg) = do_stanza(module, path, stanza, options, state, backup, create) if not module.check_mode and os.path.exists(path): file_args = module.load_file_common_arguments(module.params) changed = module.set_fs_attributes_if_different(file_args, changed) results = dict( changed=changed, diff=diff, msg=msg, path=path, ) if backup_file is not None: results['backup_file'] = backup_file # Mission complete module.exit_json(**results) if __name__ == '__main__': main() -- You received this message because you are subscribed to the Google Groups "Ansible Development" group. To unsubscribe from this group and stop receiving emails from it, send an email to ansible-devel+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.