diff --git a/lib/ansible/modules/system/gconftool2.py b/lib/ansible/modules/system/gconftool2.py new file mode 100644 index 0000000000..2e356d50e1 --- /dev/null +++ b/lib/ansible/modules/system/gconftool2.py @@ -0,0 +1,247 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +# (c) 2016, Kenneth D. Evensen +# +# This file is part of Ansible (sort of) +# +# Ansible is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Ansible 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 +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Ansible. If not, see . +from ansible.module_utils.basic import AnsibleModule, BOOLEANS_TRUE +from ansible.module_utils.pycompat24 import get_exception +import subprocess + +DOCUMENTATION = """ +module: gconftool2 +author: + - "Kenneth D. Evensen (@kevensen)" +short_description: Edit GNOME Configurations +description: + - Edit PAM service's type, control, module path and module arguments. + In order for a PAM rule to be modified, the type, control and + module_path must match an existing rule. See man(5) pam.d for details. +version_added: "2.3" +options: + key: + required: true + description: + - A GConf preference key is an element in the GConf repository + that corresponds to an application preference. See man gconftool-2(1) + value: + required: false + description: + - Preference keys typically have simple values such as strings, + integers, or lists of strings and integers. This is ignored if the state + is "get". See man gconftool-2(1) + value_type: + required: false + choices: + - int + - bool + - float + - string + description: + - The type of value being set. This is ignored if the state is "get". + state: + required: true + choices: + - get + - set + - unset + description: + - The action to take upon the key/value. + config_source: + required: false + description: + - Specify a configuration source to use rather than the default path. + See man gconftool-2(1) + direct: + required: false + choices: [ "yes", "no" ] + default: no + description: + - Access the config database directly, bypassing server. If direct is + specified then the config_source must be specified as well. + See man gconftool-2(1) + +""" + +EXAMPLES = """ +- name: Change the widget font to "Serif 12" + gconftool2: + key: "/desktop/gnome/interface/font_name" + value_type: "string" + value: "Serif 12" +""" + +RETURN = ''' + key: + description: The key specified in the module parameters + returned: success + type: string + sample: "/desktop/gnome/interface/font_name" + value_type: + description: The type of the value that was changed + returned: success + type: string + sample: "string" + value: + description: The value of the preference key after executing the module + returned: success + type: string + sample: "Serif 12" +... +''' + + +class GConf2Preference(object): + def __init__(self, ansible, key, value_type, value, + direct=False, config_source=""): + self.ansible = ansible + self.key = key + self.value_type = value_type + self.value = value + self.config_source = config_source + self.direct = direct + + def value_already_set(self): + return False + + def call(self, call_type): + config_source = '' + direct = '' + changed = False + out = '' + + # If the configuration source is different from the default, create + # the argument + if self.config_source is not None and len(self.config_source) > 0: + config_source = "--config-source " + self.config_source + + # If direct is true, create the argument + if self.direct: + direct = "--direct" + + # Execute the call + try: + # If the call is "get", then we don't need as many parameters and + # we can ignore some + if call_type == 'get': + process = subprocess.Popen(["gconftool-2 --get " + self.key], + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, shell=True) + # Otherwise, we will use all relevant parameters + else: + process = subprocess.Popen(["gconftool-2 " + direct + " " + + config_source + " --type " + + self.value_type + " --" + + call_type + " " + self.key + " " + + self.value], stdout=subprocess.PIPE, + stderr=subprocess.PIPE, shell=True) + # In either case, we will capture the output + out = process.stdout.read() + err = process.stderr.read() + + if len(err) > 0: + self.ansible.fail_json(msg='gconftool-2 failed with error: %s' + % (str(err))) + else: + changed = True + + except OSError: + self.ansible.fail_json(msg='gconftool-2 failed with and exception') + + return changed, out.rstrip() + + +def main(): + # Setup the Ansible module + module = AnsibleModule( + argument_spec=dict( + key=dict(required=True, default=None, type='str'), + value_type=dict(required=False, + choices=['int', 'bool', + 'float', 'string'], + type='str'), + value=dict(required=False, default=None, + type='str'), + state=dict(required=True, default=None, + choices=['set', 'get', 'unset'], + type='str'), + direct=dict(required=False, + default=False, type='bool'), + config_source=dict(required=False, + default=None, type='str') + ), + supports_check_mode=True + ) + + direct = False + # Assign module values to dictionary values + key = module.params['key'] + value_type = module.params['value_type'] + value = module.params['value'] + state = module.params['state'] + if module.params['direct'] in BOOLEANS_TRUE: + direct = True + config_source = module.params['config_source'] + + # Initialize some variables for later + change = False + new_value = '' + + if state != "get": + if value is None or value == "": + module.fail_json(msg='State %s requires "value" to be set' + % str(state)) + elif value_type is None or value_type == "": + module.fail_json(msg='State %s requires "value_type" to be set' + % str(state)) + + if direct and config_source is None: + module.fail_json(msg='If "direct" is "yes" then the ' + + '"config_source" must be specified') + elif not direct and config_source is not None: + module.fail_json(msg='If the "config_source" is specified ' + + 'then "direct" must be "yes"') + + # Create a gconf2 preference + gconf_pref = GConf2Preference(module, key, value_type, + value, direct, config_source) + # Now we get the current value + _, current_value = gconf_pref.call("get") + + # Check if the current value equals the value we want to set. If not, make + # a change + if current_value != value: + # If check mode, we know a change would have occured. + if module.check_mode: + # So we will set the change to True + change = True + # And set the new_value to the value that would have been set + new_value = value + # If not check mode make the change. + else: + change, new_value = gconf_pref.call(state) + # If the value we want to set is the same as the current_value, we will + # set the new_value to the current_value for reporting + else: + new_value = current_value + + facts = {} + facts['gconftool2'] = {'changed': change, 'key': key, + 'value_type': value_type, 'value': new_value} + + module.exit_json(changed=change, ansible_facts=facts) + +if __name__ == '__main__': + main() diff --git a/lib/ansible/modules/system/sysctl.py b/lib/ansible/modules/system/sysctl.py index b74193c5d4..8b744ce163 100644 --- a/lib/ansible/modules/system/sysctl.py +++ b/lib/ansible/modules/system/sysctl.py @@ -118,7 +118,7 @@ EXAMPLES = ''' import os import tempfile import re -from ansible.module_utils.basic import get_platform, AnsibleModule +from ansible.module_utils.basic import get_platform, AnsibleModule, BOOLEANS_TRUE, BOOLEANS_FALSE class SysctlModule(object):