Skip to content

Instantly share code, notes, and snippets.

@mgedmin
Last active February 6, 2024 14:21
Show Gist options
  • Save mgedmin/5f8ac034df0c371444be to your computer and use it in GitHub Desktop.
Save mgedmin/5f8ac034df0c371444be to your computer and use it in GitHub Desktop.
Ansible module for postfix configuration
#!/usr/bin/python
import subprocess
DOCUMENTATION = '''
---
module: postfix
short_description: changes postfix configuration parameters
description:
- The M(postfix) module changes postfix configuration by invoking 'postconf'.
This is needed if you don't want to use M(template) for the entire main.cf,
because M(lineinfile) cannot handle multi-line configuration values, and
solutions involving M(command) are cumbersone or don't work correctly
in check mode.
- Be sure to run C(postfix reload) (or, for settings like inet_interfaces,
C(service postfix restart)) afterwards.
options:
name:
description:
- the name of the setting
required: true
default: null
value:
description:
- the value for that setting
required: true
default: null
author:
- Marius Gedminas <[email protected]>
'''
EXAMPLES = '''
- postfix: name=myhostname value={{ ansible_fqdn }}
- postfix: name=mynetworks value="127.0.0.0/8, [::1]/128, 192.168.1.0/24"
- postfix: name={{ item.name }} value="{{ item.value }}"
with_items:
- { name: inet_interfaces, value: loopback-only }
- { name: inet_protocols, value: ipv4 }
'''
def run(args, module):
try:
cmd = subprocess.Popen(args, stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
out, err = cmd.communicate()
rc = cmd.returncode
except (OSError, IOError) as e:
module.fail_json(rc=e.errno, msg=str(e), cmd=args)
if rc != 0 or err:
module.fail_json(rc=rc, msg=err, cmd=args)
if not isinstance(out, str):
out = out.decode('UTF-8')
return out
def main():
module = AnsibleModule(
argument_spec=dict(
name=dict(type='str', required=True),
value=dict(type='str', required=True),
),
supports_check_mode=True,
)
name = module.params['name']
value = ' '.join(module.params['value'].split())
old_value = run(['postconf', '-h', name], module).strip()
if value == old_value:
module.exit_json(
msg="",
changed=False,
)
if not module.check_mode:
run(['postconf', '{}={}'.format(name, value)], module)
module.exit_json(
msg="setting changed",
diff=dict(
before_header='postconf -h {}'.format(name),
after_header='postconf -h {}'.format(name),
before=old_value + '\n',
after=value + '\n'),
changed=True,
)
from ansible.module_utils.basic import * # noqa
if __name__ == '__main__':
main()
@mgedmin
Copy link
Author

mgedmin commented May 5, 2021

Ahh, yes, sorry, I've fixed this in my private git repo but forgot to update the gist. I've pushed the latest version that works for me now, it should support both Python 2 and Python 3 without relying on subprocess.Popen() having a text argument.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment