mirror of https://dev.ccchb.de/ccchb/ansible.git
				
				
				
			
		
			
	
	
		
			284 lines
		
	
	
		
			7.6 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
		
		
			
		
	
	
			284 lines
		
	
	
		
			7.6 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
| 
								 | 
							
								#!/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()
							 |