Add the postconf ansible module to the library.

Fixes #7
This commit is contained in:
genofire 2020-10-17 03:46:13 +02:00
parent cb8403a0d3
commit 75e2c3768f
3 changed files with 413 additions and 1 deletions

View file

@ -12,7 +12,7 @@
# some basic default values... # some basic default values...
#inventory = /usr/local/etc/ansible/hosts #inventory = /usr/local/etc/ansible/hosts
#library = /usr/share/my_modules/ library = /usr/local/etc/ansible/library
#module_utils = /usr/share/my_module_utils/ #module_utils = /usr/share/my_module_utils/
#remote_tmp = ~/.ansible/tmp #remote_tmp = ~/.ansible/tmp
#local_tmp = ~/.ansible/tmp #local_tmp = ~/.ansible/tmp

129
library/postconf Normal file
View file

@ -0,0 +1,129 @@
#!/usr/bin/python
ANSIBLE_METADATA = {
'metadata_version': '1.1',
'status': ['preview'],
'supported_by': 'community'
}
DOCUMENTATION = '''
---
module: postconf
short_description: Module for Postfix postconf
version_added: "2.4"
description:
- "This is module for setup Postfix variables in main.cf with postconf command"
options:
name:
description:
- Variable name.
required: true
value:
description:
- Value of the variable. Required if C(state=present).
required: false
default: null
state:
description:
- Whether to ensure that the variable is present or absent.
required: false
default: present
choices: [ "present", "absent" ]
extends_documentation_fragment:
- system
author:
- Alexander Galato (@alet)
'''
EXAMPLES = '''
# Assign value
- name: Make myhostname be equial "gateway.home"
postconf:
name: myhostname
value: gateway.home
# Remove variable from config file
- name: Remove milter_protocol
postconf:
name: milter_protocol
state: absent
'''
from ansible.module_utils.basic import AnsibleModule
def test_var(module, postconf_path, postconf_arg):
postconf_arg += " -H"
rc, out, err = module.run_command("%s %s %s" % (postconf_path, postconf_arg, module.params["name"]))
if rc != 0:
return False
return True
def query_var(module, postconf_path, postconf_arg):
postconf_arg += " -h"
rc, out, err = module.run_command("%s %s %s" % (postconf_path, postconf_arg, module.params["name"]))
if rc != 0:
return False
if out.rstrip() != module.params["value"]:
return False
return True
def set_value(module, postconf_path, postconf_arg):
if query_var(module, postconf_path, postconf_arg):
return (False, "The variable already set in value %s" % module.params["value"])
rc, out, err = module.run_command("%s %s %s=\"%s\"" % (postconf_path, postconf_arg, module.params["name"], module.params["value"]))
if rc != 0:
module.fail_json(msg="Could not set variable")
return (True, "Variable was set")
def remove_value(module, postconf_path, postconf_arg):
if test_var(module, postconf_path, postconf_arg):
postconf_arg += " -X"
rc, out, err = module.run_command("%s %s %s" % (postconf_path, postconf_arg, module.params["name"]))
if rc == 0:
return (True, "Variable was removed")
return (False, "Variable was not removed")
def main():
module_args = dict(
name=dict(type='str', required=True),
value=dict(type='str', required=False, default=''),
state=dict(type='str', required=False, default='present', choises=["present", "absent"]),
)
module = AnsibleModule(
argument_spec = module_args,
supports_check_mode = True,
)
postconf_path = module.get_bin_path('postconf', True)
p = module.params
changed = False
message = ''
postconf_arg = ""
if p["value"] is None and p["state"] == "present" :
module.fail_json(msg="You must specify 'value' to setup variable")
if p["state"] == "present":
changed, msg = set_value(module, postconf_path, postconf_arg)
elif p["state"] == "absent":
changed, msg = remove_value(module, postconf_path, postconf_arg)
module.exit_json(changed=changed, msg=', '.join(message))
if __name__ == '__main__':
main()

283
library/sysrc Executable file
View file

@ -0,0 +1,283 @@
#!/usr/local/bin/python3.7
# -*- coding: utf-8 -*-
#
# (c) 2014, David Lundgren <dlundgren@syberisle.net>
#
# This file is part of Ansible
#
# This module is free software: you can redistribute it and/or modify
# it under the terms of the MIT license.
#
# This software is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# MIT License for more details.
#
# You should have received a copy of the MIT.
# If not, see <http://opensource.org/licenses/MIT>.
from __future__ import absolute_import, division, print_function
__metaclass__ = type
ANSIBLE_METADATA = {
'metadata_version': '1.1',
'status': ['preview'],
'supported_by': 'community'
}
DOCUMENTATION = r'''
---
author:
- David Lundgren (@dlundgren)
module: sysrc
short_description: Manage FreeBSD using sysrc
version_added: '2.10'
description:
- Manages /etc/rc.conf for FreeBSD
options:
name:
description:
- Name of variable in $dest to manage.
type: str
required: true
value:
description:
- The value if "present"
type: str
state:
description:
- Whether the var should be present or absent in $dest.
- append/subtract will add or remove the value from a list.
type: str
default: "present"
choices: [ present, absent, append, subtract ]
dest:
description:
- What file should be operated on
type: str
default: "/etc/rc.conf"
delim:
description:
- Delimiter used in append/subtract mode
default: " "
type: str
jail:
description:
- Name or ID of the jail to operate on
required: false
type: str
notes:
- The C(name) cannot use . (periods) as sysrc doesn't support OID style names
'''
EXAMPLES = r'''
---
# enable mysql in the /etc/rc.conf
- name: Configure mysql pid file
sysrc:
name: mysql_pidfile
value: "/var/run/mysqld/mysqld.pid"
# enable accf_http kld in the boot loader
- name: enable accf_http kld
sysrc:
name: accf_http_load
state: present
value: "YES"
dest: /boot/loader.conf
# add gif0 to cloned_interfaces
- name: add gif0 interface
sysrc:
name: cloned_interfaces
state: append
value: "gif0"
# enable nginx on a jail
- name: add gif0 interface
sysrc:
name: nginx_enable
value: "YES"
jail: www
'''
RETURN = r'''
changed:
description: Return changed for sysrc actions as true or false.
returned: always
type: bool
'''
from ansible.module_utils.basic import AnsibleModule
import re
class sysrc(object):
def __init__(self, module, name, value, dest, delim, jail):
self.module = module
self.name = name
self.changed = False
self.value = value
self.dest = dest
self.delim = delim
self.jail = jail
self.sysrc = module.get_bin_path('sysrc', True)
def has_unknown_variable(self, out, err):
# newer versions of sysrc use stderr instead of stdout
return err.find("unknown variable") > 0 or out.find("unknown variable") > 0
def exists(self):
# sysrc doesn't really use exit codes
(rc, out, err) = self.run_sysrc(self.name)
if self.value is None:
regex = "%s: " % re.escape(self.name)
else:
regex = "%s: %s$" % (re.escape(self.name), re.escape(self.value))
return not self.has_unknown_variable(out, err) and re.match(regex, out) is not None
def contains(self):
(rc, out, err) = self.run_sysrc('-n', self.name)
if self.has_unknown_variable(out, err):
return False
return self.value in out.strip().split(self.delim)
def create(self):
if self.module.check_mode:
self.changed = True
return
self.module._verbosity = 5
(rc, out, err) = self.run_sysrc("%s=%s" % (self.name, self.value))
if out.find("%s:" % self.name) == 0 and re.search("-> %s$" % re.escape(self.value), out) is not None:
self.changed = True
return True
else:
return False
def destroy(self):
if self.module.check_mode:
self.changed = True
return
(rc, out, err) = self.run_sysrc('-x', self.name)
if self.has_unknown_variable(out, err):
return False
self.changed = True
return True
def append(self):
if self.module.check_mode:
self.changed = True
return
setstring = '%s+=%s%s' % (self.name, self.delim, self.value)
(rc, out, err) = self.run_sysrc(setstring)
if out.find("%s:" % self.name) == 0:
values = out.split(' -> ')[1].strip().split(self.delim)
if self.value in values:
self.changed = True
return True
else:
return False
else:
return False
def subtract(self):
if self.module.check_mode:
self.changed = True
return
setstring = '%s-=%s%s' % (self.name, self.delim, self.value)
(rc, out, err) = self.run_sysrc(setstring)
if out.find("%s:" % self.name) == 0:
values = out.split(' -> ')[1].strip().split(self.delim)
if self.value in values:
return False
else:
self.changed = True
return True
else:
return False
def run_sysrc(self, *args):
cmd = [self.sysrc, '-f', self.dest]
if self.jail:
cmd += ['-j', self.jail]
cmd.extend(args)
(rc, out, err) = self.module.run_command(cmd)
if self.module._verbosity > 0:
self.cmd = cmd
if self.module._verbosity >= 4:
self.cmd_output = out
return (rc, out, err)
def main():
module = AnsibleModule(
argument_spec=dict(
name=dict(type='str', required=True),
value=dict(type='str', default=None),
state=dict(type='str', default='present', choices=['present', 'absent', 'append', 'subtract']),
dest=dict(type='str', default='/etc/rc.conf'),
delim=dict(type='str', default=' '),
jail=dict(type='str', default=None),
),
supports_check_mode=True,
)
name = module.params.pop('name')
# OID style names are not supported
if not re.match('^[a-zA-Z0-9_]+$', name):
module.fail_json(
msg="Name may only contain alpha-numeric and underscore characters"
)
value = module.params.pop('value')
state = module.params.pop('state')
dest = module.params.pop('dest')
delim = module.params.pop('delim')
jail = module.params.pop('jail')
result = dict(
name=name,
state=state,
value=value,
dest=dest,
delim=delim,
jail=jail
)
rcValue = sysrc(module, name, value, dest, delim, jail)
if module._verbosity >= 4:
result['existed'] = rcValue.exists()
if state == 'present':
not rcValue.exists() and rcValue.create()
elif state == 'absent':
rcValue.exists() and rcValue.destroy()
elif state == 'append':
not rcValue.contains() and rcValue.append()
elif state == 'subtract':
rcValue.contains() and rcValue.subtract()
if module._verbosity > 0:
result['command'] = ' '.join(rcValue.cmd)
if module._verbosity >= 4:
result['output'] = rcValue.cmd_output
result['changed'] = rcValue.changed
module.exit_json(**result)
if __name__ == '__main__':
main()