#!/usr/bin/python # -*- coding: utf-8 -*- # Copyright: (c) 2018, Rafael Bodill # Copyright: (c) 2020, Borjan Tchakaloff # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) ANSIBLE_METADATA = { 'metadata_version': '1.1', 'status': ['preview'], 'supported_by': 'community' } DOCUMENTATION = ''' --- module: device_defaults short_description: Manage Syncthing device default configurations version_added: "2.7" description: - "This module allows you to manage Syncthing device default configurations. You can update the default configurations using this module. It uses the Syncthing REST API to perform these operations." options: addresses: description: - List of addresses for the device. type: list required: false allowedNetworks: description: - List of allowed networks for the device. type: list required: false autoAcceptFolders: description: - Whether the device should automatically accept shared folders. type: bool required: false certName: description: - The certificate name for the device. type: str required: false compression: description: - The compression setting for the device. type: str required: false deviceID: description: - The ID of the device. type: str required: false ignoredFolders: description: - List of ignored folders for the device. type: list required: false introducedBy: description: - The device that introduced this device. type: str required: false introducer: description: - Whether this device is an introducer. type: bool required: false maxRecvKbps: description: - The maximum receive rate for the device in Kbps. type: int required: false maxRequestKiB: description: - The maximum request size for the device in KiB. type: int required: false maxSendKbps: description: - The maximum send rate for the device in Kbps. type: int required: false name: description: - The name of the device. type: str required: false numConnections: description: - The number of connections for the device. type: int required: false paused: description: - Whether the device is paused. type: bool required: false remoteGUIPort: description: - The remote GUI port for the device. type: int required: false skipIntroductionRemovals: description: - Whether to skip introduction removals for the device. type: bool required: false untrusted: description: - Whether the device is untrusted. type: bool required: false author: - Rafael Bodill (@rafi) ''' EXAMPLES = ''' # Get/Update device_defaults - name: Get device_defaults become: yes become_user: syncthing community.syncthing.device_defaults: host: http://localhost unix_socket: /run/syncthing/syncthing.sock config_file: /var/lib/syncthing/.config/syncthing/config.xml addresses: ["dynamic"] autoAcceptFolders: false compression: "metadata" deviceID: "device-id" name: "device-name" paused: false register: device_defaults ''' RETURN = ''' device_defaults: description: The default configuration of the device after the operation. type: dict changed: description: Whether any changes were made. type: bool response: description: The API response, in-case of an error. type: dict ''' from ansible_collections.community.syncthing.plugins.module_utils.syncthing_api import SyncthingModule import json def deep_equal(a, b): return json.dumps(a, sort_keys=True) == json.dumps(b, sort_keys=True) def run_module(): module_args = dict( addresses=dict(type='list', required=False), allowedNetworks=dict(type='list', required=False), autoAcceptFolders=dict(type='bool', required=False), certName=dict(type='str', required=False), compression=dict(type='str', required=False), deviceID=dict(type='str', required=False), ignoredFolders=dict(type='list', required=False), introducedBy=dict(type='str', required=False), introducer=dict(type='bool', required=False), maxRecvKbps=dict(type='int', required=False), maxRequestKiB=dict(type='int', required=False), maxSendKbps=dict(type='int', required=False), name=dict(type='str', required=False), numConnections=dict(type='int', required=False), paused=dict(type='bool', required=False), remoteGUIPort=dict(type='int', required=False), skipIntroductionRemovals=dict(type='bool', required=False), untrusted=dict(type='bool', required=False), ) module = SyncthingModule( api_url='/rest/config/defaults/device', argument_spec=module_args, ) current_config = module.get_call() module_args_keys_list = list(module_args.keys()) changes = {} for key, value in module.params.items(): # Check if the key is in module_args_keys_list if key in module_args_keys_list: # Check if the value is not None if value is not None: # Check if the value is different from the current_config if not deep_equal(value, current_config.get(key)): # If all conditions are met, add the key-value pair to changes changes[key] = value if module.check_mode or len(changes.keys()) == 0: module.result['device_defaults'] = current_config module.exit_json() module.patch_call(data=module.params) module.result['device_defaults'] = module.get_call() module.result['changed'] = True module.result['changes'] = changes module.exit_json() def main(): run_module() if __name__ == '__main__': main()