diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-13 12:04:41 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-13 12:04:41 +0000 |
commit | 975f66f2eebe9dadba04f275774d4ab83f74cf25 (patch) | |
tree | 89bd26a93aaae6a25749145b7e4bca4a1e75b2be /ansible_collections/community/general/plugins/modules/sysrc.py | |
parent | Initial commit. (diff) | |
download | ansible-975f66f2eebe9dadba04f275774d4ab83f74cf25.tar.xz ansible-975f66f2eebe9dadba04f275774d4ab83f74cf25.zip |
Adding upstream version 7.7.0+dfsg.upstream/7.7.0+dfsg
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'ansible_collections/community/general/plugins/modules/sysrc.py')
-rw-r--r-- | ansible_collections/community/general/plugins/modules/sysrc.py | 259 |
1 files changed, 259 insertions, 0 deletions
diff --git a/ansible_collections/community/general/plugins/modules/sysrc.py b/ansible_collections/community/general/plugins/modules/sysrc.py new file mode 100644 index 000000000..9652b629a --- /dev/null +++ b/ansible_collections/community/general/plugins/modules/sysrc.py @@ -0,0 +1,259 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright (c) 2019 David Lundgren <dlundgren@syberisle.net> +# +# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt) +# SPDX-License-Identifier: GPL-3.0-or-later + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +DOCUMENTATION = r''' +--- +author: + - David Lundgren (@dlundgren) +module: sysrc +short_description: Manage FreeBSD using sysrc +version_added: '2.0.0' +description: + - Manages C(/etc/rc.conf) for FreeBSD. +extends_documentation_fragment: + - community.general.attributes +attributes: + check_mode: + support: full + diff_mode: + support: none +options: + name: + description: + - Name of variable in C(/etc/rc.conf) to manage. + type: str + required: true + value: + description: + - The value to set when I(state=present). + - The value to add when I(state=value_present). + - The value to remove when I(state=value_absent). + type: str + state: + description: + - Use I(present) to add the variable. + - Use I(absent) to remove the variable. + - Use I(value_present) to add the value to the existing variable. + - Use I(value_absent) to remove the value from the existing variable. + type: str + default: "present" + choices: [ absent, present, value_present, value_absent ] + path: + description: + - Path to file to use instead of C(/etc/rc.conf). + type: str + default: "/etc/rc.conf" + delim: + description: + - Delimiter to be used instead of C( ). + - Only used when I(state=value_present) or I(state=value_absent). + default: " " + type: str + jail: + description: + - Name or ID of the jail to operate on. + type: str +notes: + - The C(name) cannot contain periods as sysrc does not support OID style names. +''' + +EXAMPLES = r''' +--- +# enable mysql in the /etc/rc.conf +- name: Configure mysql pid file + community.general.sysrc: + name: mysql_pidfile + value: "/var/run/mysqld/mysqld.pid" + +# enable accf_http kld in the boot loader +- name: Enable accf_http kld + community.general.sysrc: + name: accf_http_load + state: present + value: "YES" + path: /boot/loader.conf + +# add gif0 to cloned_interfaces +- name: Add gif0 interface + community.general.sysrc: + name: cloned_interfaces + state: value_present + value: "gif0" + +# enable nginx on a jail +- name: Enable nginx in test jail + community.general.sysrc: + name: nginx_enable + value: "YES" + jail: testjail +''' + +RETURN = r''' +changed: + description: Return changed for sysrc actions. + returned: always + type: bool + sample: true +''' + +from ansible.module_utils.basic import AnsibleModule +import re + + +class Sysrc(object): + def __init__(self, module, name, value, path, delim, jail): + self.module = module + self.name = name + self.changed = False + self.value = value + self.path = path + 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 present(self): + if self.exists(): + return + + if self.module.check_mode: + self.changed = True + return + + (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 + + def absent(self): + if not self.exists(): + return + + # inversed since we still need to mark as changed + if not self.module.check_mode: + (rc, out, err) = self.run_sysrc('-x', self.name) + if self.has_unknown_variable(out, err): + return + + self.changed = True + + def value_present(self): + if self.contains(): + return + + 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 + + def value_absent(self): + if not self.contains(): + return + + 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 not in values: + self.changed = True + + def run_sysrc(self, *args): + cmd = [self.sysrc, '-f', self.path] + if self.jail: + cmd += ['-j', self.jail] + cmd.extend(args) + + (rc, out, err) = self.module.run_command(cmd) + + 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=['absent', 'present', 'value_present', 'value_absent']), + path=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') + path = module.params.pop('path') + delim = module.params.pop('delim') + jail = module.params.pop('jail') + result = dict( + name=name, + state=state, + value=value, + path=path, + delim=delim, + jail=jail + ) + + rc_value = Sysrc(module, name, value, path, delim, jail) + + if state == 'present': + rc_value.present() + elif state == 'absent': + rc_value.absent() + elif state == 'value_present': + rc_value.value_present() + elif state == 'value_absent': + rc_value.value_absent() + + result['changed'] = rc_value.changed + + module.exit_json(**result) + + +if __name__ == '__main__': + main() |