def main(): """main entry point for Ansible module """ argument_spec = dict( rpc=dict(required=True), args=dict(type='dict'), output=dict(default='xml', choices=['xml', 'json', 'text']), ) argument_spec.update(junos_argument_spec) module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=False) warnings = list() check_args(module, warnings) result = {'changed': False, 'warnings': warnings} rpc = str(module.params['rpc']).replace('_', '-') if all((module.check_mode, not rpc.startswith('get'))): module.fail_json(msg='invalid rpc for running in check_mode') args = module.params['args'] or {} xattrs = {'format': module.params['output']} element = Element(module.params['rpc'], xattrs) for key, value in iteritems(args): key = str(key).replace('_', '-') if isinstance(value, list): for item in value: child = SubElement(element, key) if item is not True: child.text = item else: child = SubElement(element, key) if value is not True: child.text = value reply = send_request(module, element) result['xml'] = str(tostring(reply)) if module.params['output'] == 'text': data = reply.find('.//output') result['output'] = data.text.strip() result['output_lines'] = result['output'].split('\n') elif module.params['output'] == 'json': result['output'] = module.from_json(reply.text.strip()) else: result['output'] = str(tostring(reply)).split('\n') module.exit_json(**result)
def main(): """main entry point for execution """ argument_spec = dict( config=dict(required=True, type='str'), commit=dict(type='bool'), replace=dict(type='str'), rollback=dict(type='int'), commit_comment=dict(type='str'), defaults=dict(default=False, type='bool'), multiline_delimiter=dict(type='str'), diff_replace=dict(choices=['line', 'block', 'config']), diff_match=dict(choices=['line', 'strict', 'exact', 'none']), diff_ignore_lines=dict(type='list')) module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=True) result = {'changed': False} connection = Connection(module._socket_path) capabilities = module.from_json(connection.get_capabilities()) if capabilities: validate_args(module, capabilities) if module.params['defaults']: if 'get_default_flag' in capabilities.get('rpc'): flags = connection.get_default_flag() else: flags = 'all' else: flags = [] candidate = to_text(module.params['config']) running = connection.get_config(flags=flags) try: result.update(run(module, capabilities, connection, candidate, running)) except Exception as exc: module.fail_json(msg=to_text(exc)) module.exit_json(**result)
def main(): """entry point for module execution """ argument_spec = dict( command=dict(type="str", required=True), prompt=dict(type="list", required=False), answer=dict(type="list", required=False), newline=dict(type="bool", default=True, required=False), sendonly=dict(type="bool", default=False, required=False), check_all=dict(type="bool", default=False, required=False), ) required_together = [["prompt", "answer"]] module = AnsibleModule( argument_spec=argument_spec, required_together=required_together, supports_check_mode=True, ) if module.check_mode and not module.params["command"].startswith("show"): module.fail_json( msg="Only show commands are supported when using check_mode, not " "executing %s" % module.params["command"] ) warnings = list() result = {"changed": False, "warnings": warnings} connection = Connection(module._socket_path) response = "" try: response = connection.get(**module.params) except ConnectionError as exc: module.fail_json(msg=to_text(exc, errors="surrogate_then_replace")) if not module.params["sendonly"]: try: result["json"] = module.from_json(response) except ValueError: pass result.update({"stdout": response}) module.exit_json(**result)
def main(): """entry point for module execution """ argument_spec = dict( command=dict(type='str', required=True), prompt=dict(type='list', required=False), answer=dict(type='list', required=False), newline=dict(type='bool', default=True, required=False), sendonly=dict(type='bool', default=False, required=False), check_all=dict(type='bool', default=False, required=False), ) required_together = [['prompt', 'answer']] module = AnsibleModule(argument_spec=argument_spec, required_together=required_together, supports_check_mode=True) if module.check_mode and not module.params['command'].startswith('show'): module.fail_json( msg='Only show commands are supported when using check_mode, not ' 'executing %s' % module.params['command'] ) warnings = list() result = {'changed': False, 'warnings': warnings} connection = Connection(module._socket_path) response = '' try: response = connection.get(**module.params) except ConnectionError as exc: module.fail_json(msg=to_text(exc, errors='surrogate_then_replace')) if not module.params['sendonly']: try: result['json'] = module.from_json(response) except ValueError: pass result.update({ 'stdout': response, }) module.exit_json(**result)
def main(): """ main entry point for Ansible module """ argument_spec = {} module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=True) connection = Connection(module._socket_path) facts = connection.get_capabilities() facts = module.from_json(facts) result = { 'changed': False, 'ansible_facts': { 'cisco_ios': { 'capabilities': facts['device_info'] } } } module.exit_json(**result)
def main(): """main entry point for module execution """ argument_spec = dict(command=dict(required=True), ) module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=True) command = module.params['command'] connection = Connection(module._socket_path) output = connection.get(command) try: json_out = module.from_json(output) except: json_out = None result = {'changed': False, 'stdout': output, 'json': json_out} module.exit_json(**result)
class NitroAPICaller(object): _argument_spec = dict( nsip=dict( fallback=(env_fallback, ['NETSCALER_NSIP']), aliases=['mas_ip'], ), nitro_user=dict( fallback=(env_fallback, ['NETSCALER_NITRO_USER']), aliases=['mas_user'], ), nitro_pass=dict(fallback=(env_fallback, ['NETSCALER_NITRO_PASS']), aliases=['mas_pass'], no_log=True), nitro_protocol=dict(type='str', choices=['http', 'https'], fallback=(env_fallback, ['NETSCALER_NITRO_PROTOCOL']), default='https'), validate_certs=dict(default=True, type='bool'), nitro_auth_token=dict(type='str', aliases=['mas_auth_token'], no_log=True), resource=dict(type='str'), name=dict(type='str'), attributes=dict(type='dict'), args=dict(type='dict'), filter=dict(type='dict'), operation=dict( type='str', choices=[ 'add', 'update', 'get', 'get_by_args', 'get_filtered', 'get_all', 'delete', 'delete_by_args', 'count', 'mas_login', # Actions 'save_config', # Generic action handler 'action', ]), expected_nitro_errorcode=dict( type='list', elements='int', default=[0], ), action=dict(type='str'), mas_proxy_call=dict(default=False, type='bool'), instance_ip=dict(type='str'), instance_name=dict(type='str'), instance_id=dict(type='str'), timeout=dict(type='int', default=45), idempotent=dict(type='bool', default=False), ) def __init__(self): self._module = AnsibleModule( argument_spec=self._argument_spec, supports_check_mode=False, ) self._module_result = dict(failed=False, ) # Prepare the http headers according to module arguments self._headers = {} self._headers['Content-Type'] = 'application/json' # Check for conflicting authentication methods have_token = self._module.params['nitro_auth_token'] is not None have_userpass = None not in (self._module.params['nitro_user'], self._module.params['nitro_pass']) login_operation = self._module.params['operation'] == 'mas_login' if have_token and have_userpass: self.fail_module( msg= 'Cannot define both authentication token and username/password' ) if have_token: self._headers[ 'Cookie'] = "NITRO_AUTH_TOKEN=%s" % self._module.params[ 'nitro_auth_token'] if have_userpass and not login_operation: self._headers['X-NITRO-USER'] = self._module.params['nitro_user'] self._headers['X-NITRO-PASS'] = self._module.params['nitro_pass'] # Do header manipulation when doing a MAS proxy call if self._module.params.get( 'mas_proxy_call') is not None and self._module.params.get( 'mas_proxy_call'): if self._module.params['instance_ip'] is not None: self._headers[ '_MPS_API_PROXY_MANAGED_INSTANCE_IP'] = self._module.params[ 'instance_ip'] elif self._module.params['instance_name'] is not None: self._headers[ '_MPS_API_PROXY_MANAGED_INSTANCE_NAME'] = self._module.params[ 'instance_name'] elif self._module.params['instance_id'] is not None: self._headers[ '_MPS_API_PROXY_MANAGED_INSTANCE_ID'] = self._module.params[ 'instance_id'] def edit_response_data(self, r, info, result, success_status): # Search for body in both http body and http data if r is not None: result['http_response_body'] = codecs.decode(r.read(), 'utf-8') elif 'body' in info: result['http_response_body'] = codecs.decode(info['body'], 'utf-8') del info['body'] else: result['http_response_body'] = '' result['http_response_data'] = info # Update the nitro_* parameters according to expected success_status # Use explicit return values from http response or deduce from http status code # Nitro return code in http data result['nitro_errorcode'] = None result['nitro_message'] = None result['nitro_severity'] = None if result['http_response_body'] != '': try: data = self._module.from_json(result['http_response_body']) except ValueError: data = {} result['nitro_errorcode'] = data.get('errorcode') result['nitro_message'] = data.get('message') result['nitro_severity'] = data.get('severity') # If we do not have the nitro errorcode from body deduce it from the http status if result['nitro_errorcode'] is None: # HTTP status failed if result['http_response_data'].get('status') != success_status: result['nitro_errorcode'] = -1 result['nitro_message'] = result['http_response_data'].get( 'msg', 'HTTP status %s' % result['http_response_data']['status']) result['nitro_severity'] = 'ERROR' # HTTP status succeeded else: result['nitro_errorcode'] = 0 result['nitro_message'] = 'Success' result['nitro_severity'] = 'NONE' def handle_get_return_object(self, result): result['nitro_object'] = [] if result['nitro_errorcode'] == 0: if result['http_response_body'] != '': data = self._module.from_json(result['http_response_body']) if self._module.params['resource'] in data: result['nitro_object'] = data[ self._module.params['resource']] else: del result['nitro_object'] def fail_module(self, msg, **kwargs): self._module_result['failed'] = True self._module_result['changed'] = False self._module_result.update(kwargs) self._module_result['msg'] = msg self._module_result['headers'] = self._headers self._module.fail_json(**self._module_result) def main(self): if self._module.params['operation'] == 'add': result = self.add() if self._module.params['operation'] == 'update': result = self.update() if self._module.params['operation'] == 'delete': result = self.delete() if self._module.params['operation'] == 'delete_by_args': result = self.delete_by_args() if self._module.params['operation'] == 'get': result = self.get() if self._module.params['operation'] == 'get_by_args': result = self.get_by_args() if self._module.params['operation'] == 'get_filtered': result = self.get_filtered() if self._module.params['operation'] == 'get_all': result = self.get_all() if self._module.params['operation'] == 'count': result = self.count() if self._module.params['operation'] == 'mas_login': result = self.mas_login() if self._module.params['operation'] == 'action': result = self.action() if self._module.params['operation'] == 'save_config': result = self.save_config() if result['nitro_errorcode'] not in self._module.params[ 'expected_nitro_errorcode']: self.fail_module(msg='NITRO Failure', **result) self._module_result.update(result) self._module.exit_json(**self._module_result) def exit_module(self): self._module.exit_json() def add(self): # Check if required attributes are present if self._module.params['resource'] is None: self.fail_module(msg='NITRO resource is undefined.') if self._module.params['attributes'] is None: self.fail_module(msg='NITRO resource attributes are undefined.') # Handle idempotent flag idempotent_querystring = '' idempotent_flag = self._module.params.get('idempotent') if idempotent_flag is not None and idempotent_flag: idempotent_querystring = '?idempotent=yes' url = '%s://%s/nitro/v1/config/%s%s' % ( self._module.params['nitro_protocol'], self._module.params['nsip'], self._module.params['resource'], idempotent_querystring, ) data = self._module.jsonify({ self._module.params['resource']: self._module.params['attributes'] }) timeout = self._module.params['timeout'] r, info = fetch_url( self._module, url=url, headers=self._headers, data=data, method='POST', timeout=timeout, ) result = {} self.edit_response_data(r, info, result, success_status=201) if result['nitro_errorcode'] == 0: self._module_result['changed'] = True else: self._module_result['changed'] = False return result def update(self): # Check if required attributes are arguments present if self._module.params['resource'] is None: self.fail_module(msg='NITRO resource is undefined.') if self._module.params['name'] is None: self.fail_module(msg='NITRO resource name is undefined.') if self._module.params['attributes'] is None: self.fail_module(msg='NITRO resource attributes are undefined.') # Handle idempotent flag idempotent_querystring = '' idempotent_flag = self._module.params.get('idempotent') if idempotent_flag is not None and idempotent_flag: idempotent_querystring = '?idempotent=yes' url = '%s://%s/nitro/v1/config/%s/%s%s' % ( self._module.params['nitro_protocol'], self._module.params['nsip'], self._module.params['resource'], self._module.params['name'], idempotent_querystring, ) data = self._module.jsonify({ self._module.params['resource']: self._module.params['attributes'] }) timeout = self._module.params['timeout'] r, info = fetch_url( self._module, url=url, headers=self._headers, data=data, method='PUT', timeout=timeout, ) result = {} self.edit_response_data(r, info, result, success_status=200) if result['nitro_errorcode'] == 0: self._module_result['changed'] = True else: self._module_result['changed'] = False return result def get(self): if self._module.params['resource'] is None: self.fail_module(msg='NITRO resource is undefined.') if self._module.params['name'] is None: self.fail_module(msg='NITRO resource name is undefined.') url = '%s://%s/nitro/v1/config/%s/%s' % ( self._module.params['nitro_protocol'], self._module.params['nsip'], self._module.params['resource'], self._module.params['name'], ) timeout = self._module.params['timeout'] r, info = fetch_url( self._module, url=url, headers=self._headers, method='GET', timeout=timeout, ) result = {} self.edit_response_data(r, info, result, success_status=200) self.handle_get_return_object(result) self._module_result['changed'] = False return result def get_by_args(self): if self._module.params['resource'] is None: self.fail_module(msg='NITRO resource is undefined.') if self._module.params['args'] is None: self.fail_module(msg='NITRO args is undefined.') url = '%s://%s/nitro/v1/config/%s' % ( self._module.params['nitro_protocol'], self._module.params['nsip'], self._module.params['resource'], ) args_dict = self._module.params['args'] args = ','.join(['%s:%s' % (k, args_dict[k]) for k in args_dict]) args = 'args=' + args url = '?'.join([url, args]) timeout = self._module.params['timeout'] r, info = fetch_url( self._module, url=url, headers=self._headers, method='GET', timeout=timeout, ) result = {} self.edit_response_data(r, info, result, success_status=200) self.handle_get_return_object(result) self._module_result['changed'] = False return result def get_filtered(self): if self._module.params['resource'] is None: self.fail_module(msg='NITRO resource is undefined.') if self._module.params['filter'] is None: self.fail_module(msg='NITRO filter is undefined.') keys = list(self._module.params['filter'].keys()) filter_key = keys[0] filter_value = self._module.params['filter'][filter_key] filter_str = '%s:%s' % (filter_key, filter_value) url = '%s://%s/nitro/v1/config/%s?filter=%s' % ( self._module.params['nitro_protocol'], self._module.params['nsip'], self._module.params['resource'], filter_str, ) timeout = self._module.params['timeout'] r, info = fetch_url( self._module, url=url, headers=self._headers, method='GET', timeout=timeout, ) result = {} self.edit_response_data(r, info, result, success_status=200) self.handle_get_return_object(result) self._module_result['changed'] = False return result def get_all(self): if self._module.params['resource'] is None: self.fail_module(msg='NITRO resource is undefined.') url = '%s://%s/nitro/v1/config/%s' % ( self._module.params['nitro_protocol'], self._module.params['nsip'], self._module.params['resource'], ) self._module.debug('headers %s' % self._headers) timeout = self._module.params['timeout'] r, info = fetch_url( self._module, url=url, headers=self._headers, method='GET', timeout=timeout, ) result = {} self.edit_response_data(r, info, result, success_status=200) self.handle_get_return_object(result) self._module_result['changed'] = False return result def delete(self): if self._module.params['resource'] is None: self.fail_module(msg='NITRO resource is undefined.') if self._module.params['name'] is None: self.fail_module(msg='NITRO resource is undefined.') # Deletion by name takes precedence over deletion by attributes url = '%s://%s/nitro/v1/config/%s/%s' % ( self._module.params['nitro_protocol'], self._module.params['nsip'], self._module.params['resource'], self._module.params['name'], ) timeout = self._module.params['timeout'] r, info = fetch_url( self._module, url=url, headers=self._headers, method='DELETE', timeout=timeout, ) result = {} self.edit_response_data(r, info, result, success_status=200) if result['nitro_errorcode'] == 0: self._module_result['changed'] = True else: self._module_result['changed'] = False return result def delete_by_args(self): if self._module.params['resource'] is None: self.fail_module(msg='NITRO resource is undefined.') if self._module.params['args'] is None: self.fail_module(msg='NITRO args is undefined.') url = '%s://%s/nitro/v1/config/%s' % ( self._module.params['nitro_protocol'], self._module.params['nsip'], self._module.params['resource'], ) args_dict = self._module.params['args'] args = ','.join(['%s:%s' % (k, args_dict[k]) for k in args_dict]) args = 'args=' + args url = '?'.join([url, args]) timeout = self._module.params['timeout'] r, info = fetch_url( self._module, url=url, headers=self._headers, method='DELETE', timeout=timeout, ) result = {} self.edit_response_data(r, info, result, success_status=200) if result['nitro_errorcode'] == 0: self._module_result['changed'] = True else: self._module_result['changed'] = False return result def count(self): if self._module.params['resource'] is None: self.fail_module(msg='NITRO resource is undefined.') url = '%s://%s/nitro/v1/config/%s?count=yes' % ( self._module.params['nitro_protocol'], self._module.params['nsip'], self._module.params['resource'], ) timeout = self._module.params['timeout'] r, info = fetch_url( self._module, url=url, headers=self._headers, method='GET', timeout=timeout, ) result = {} self.edit_response_data(r, info, result) if result['http_response_body'] != '': data = self._module.from_json(result['http_response_body']) result['nitro_errorcode'] = data['errorcode'] result['nitro_message'] = data['message'] result['nitro_severity'] = data['severity'] if self._module.params['resource'] in data: result['nitro_count'] = data[ self._module.params['resource']][0]['__count'] self._module_result['changed'] = False return result def action(self): # Check if required attributes are present if self._module.params['resource'] is None: self.fail_module(msg='NITRO resource is undefined.') if self._module.params['attributes'] is None: self.fail_module(msg='NITRO resource attributes are undefined.') if self._module.params['action'] is None: self.fail_module(msg='NITRO action is undefined.') url = '%s://%s/nitro/v1/config/%s?action=%s' % ( self._module.params['nitro_protocol'], self._module.params['nsip'], self._module.params['resource'], self._module.params['action'], ) data = self._module.jsonify({ self._module.params['resource']: self._module.params['attributes'] }) timeout = self._module.params['timeout'] r, info = fetch_url( self._module, url=url, headers=self._headers, data=data, method='POST', timeout=timeout, ) result = {} self.edit_response_data(r, info, result, success_status=200) if result['nitro_errorcode'] == 0: self._module_result['changed'] = True else: self._module_result['changed'] = False return result def mas_login(self): url = '%s://%s/nitro/v1/config/login' % ( self._module.params['nitro_protocol'], self._module.params['nsip'], ) login_credentials = { 'login': { 'username': self._module.params['nitro_user'], 'password': self._module.params['nitro_pass'], } } data = 'object=\n%s' % self._module.jsonify(login_credentials) timeout = self._module.params['timeout'] r, info = fetch_url( self._module, url=url, headers=self._headers, data=data, method='POST', timeout=timeout, ) self._module.debug(r) self._module.debug(info) result = {} self.edit_response_data(r, info, result, success_status=200) if result['nitro_errorcode'] == 0: body_data = self._module.from_json(result['http_response_body']) result['nitro_auth_token'] = body_data['login'][0]['sessionid'] self._module_result['changed'] = False return result def save_config(self): url = '%s://%s/nitro/v1/config/nsconfig?action=save' % ( self._module.params['nitro_protocol'], self._module.params['nsip'], ) data = self._module.jsonify({ 'nsconfig': {}, }) timeout = self._module.params['timeout'] r, info = fetch_url( self._module, url=url, headers=self._headers, data=data, method='POST', timeout=timeout, ) result = {} self.edit_response_data(r, info, result, success_status=200) self._module_result['changed'] = False return result
def main(): """main entry point for Ansible module """ argument_spec = dict( rpc=dict(required=True), args=dict(type='dict'), attrs=dict(type='dict'), output=dict(default='xml', choices=['xml', 'json', 'text']), ) argument_spec.update(junos_argument_spec) module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=False) warnings = list() result = {'changed': False, 'warnings': warnings} rpc = str(module.params['rpc']).replace('_', '-') if all((module.check_mode, not rpc.startswith('get'))): module.fail_json(msg='invalid rpc for running in check_mode') args = module.params['args'] or {} attrs = module.params['attrs'] or {} xattrs = {'format': module.params['output']} for key, value in iteritems(attrs): xattrs.update({key: value}) element = Element(module.params['rpc'], xattrs) for key, value in iteritems(args): key = str(key).replace('_', '-') if isinstance(value, list): for item in value: child = SubElement(element, key) if item is not True: child.text = item else: child = SubElement(element, key) if value is not True: child.text = value reply = exec_rpc(module, tostring(element), ignore_warning=False) result['xml'] = tostring(reply) if module.params['output'] == 'text': data = reply.find('.//output') result['output'] = data.text.strip() result['output_lines'] = result['output'].split('\n') elif module.params['output'] == 'json': result['output'] = module.from_json(reply.text.strip()) else: result['output'] = tostring(reply).split('\n') module.exit_json(**result)
def main(): argument_spec = dict(command=dict(type='str', required=True), prompt=dict(type='list', required=False), answer=dict(type='list', required=False), compare=dict(type='dict', required=False), sendonly=dict(type='bool', default=False, required=False), # newline=dict(type='bool', default=True, required=False), # check_all=dict(type='bool', default=False, required=False), ) required_together = [['prompt', 'answer']] module = AnsibleModule(argument_spec=argument_spec, required_together=required_together, supports_check_mode=True) if not PY3: module.fail_json(msg="pyATS/Genie requires Python 3") if not HAS_GENIE: module.fail_json(msg="Genie not found. Run 'pip install genie'") if not HAS_PYATS: module.fail_json(msg="pyATS not found. Run 'pip install pyats'") if module.check_mode and not module.params['command'].startswith('show'): module.fail_json( msg='Only show commands are supported when using check_mode, not ' 'executing %s' % module.params['command'] ) warnings = list() result = {'changed': False, 'warnings': warnings} connection = Connection(module._socket_path) capabilities = json.loads(connection.get_capabilities()) if capabilities['device_info']['network_os'] == 'ios': genie_os = 'iosxe' else: genie_os = capabilities['device_info']['network_os'] compare = module.params.pop('compare') response = '' try: response = connection.get(**module.params) except ConnectionError as exc: module.fail_json(msg=to_text(exc, errors='surrogate_then_replace')) device = Device("uut", os=genie_os) device.custom.setdefault("abstraction", {})["order"] = ["os"] device.cli = AttrDict({"execute": None}) try: get_parser(module.params['command'], device) except Exception as e: module.fail_json(msg="Unable to find parser for command '{0}' ({1})".format(module.params['command'], e)) try: parsed_output = device.parse(module.params['command'], output=response) except Exception as e: module.fail_json(msg="Unable to parse output for command '{0}' ({1})".format(module.params['command'], e)) # import sys; # sys.stdin = open('/dev/tty') # import pdb; # pdb.set_trace() if compare: diff = Diff(parsed_output, compare, exclude=get_parser_exclude(module.params['command'], device)) diff.findDiff() else: diff = None if not module.params['sendonly']: try: result['json'] = module.from_json(response) except ValueError: pass result.update({ 'stdout': response, 'structured': parsed_output, 'diff': "{0}".format(diff), 'exclude': get_parser_exclude(module.params['command'], device), }) module.exit_json(**result)
def main(): argument_spec = get_default_argspec() argument_spec.update( dict( url=dict(type='str'), method=dict(type='str', choices=['get', 'post', 'directory-only'], default='get'), content=dict(type='str'), fail_on_acme_error=dict(type='bool', default=True), )) module = AnsibleModule( argument_spec=argument_spec, mutually_exclusive=(['account_key_src', 'account_key_content'], ), required_if=( ['method', 'get', ['url']], ['method', 'post', ['url', 'content']], [ 'method', 'get', ['account_key_src', 'account_key_content'], True ], [ 'method', 'post', ['account_key_src', 'account_key_content'], True ], ), ) backend = create_backend(module, False) result = dict() changed = False try: # Get hold of ACMEClient and ACMEAccount objects (includes directory) client = ACMEClient(module, backend) method = module.params['method'] result['directory'] = client.directory.directory # Do we have to do more requests? if method != 'directory-only': url = module.params['url'] fail_on_acme_error = module.params['fail_on_acme_error'] # Do request if method == 'get': data, info = client.get_request(url, parse_json_result=False, fail_on_error=False) elif method == 'post': changed = True # only POSTs can change data, info = client.send_signed_request( url, to_bytes(module.params['content']), parse_json_result=False, encode_payload=False, fail_on_error=False) # Update results result.update(dict( headers=info, output_text=to_native(data), )) # See if we can parse the result as JSON try: result['output_json'] = module.from_json(to_text(data)) except Exception as dummy: pass # Fail if error was returned if fail_on_acme_error and info['status'] >= 400: raise ACMEProtocolException(info=info, content_json=result) # Done! module.exit_json(changed=changed, **result) except ModuleFailException as e: e.do_fail(module, **result)
def main(): spec = dict( gather_subset=dict(default=['!config'], type='list') ) spec.update(iosxr_argument_spec) module = AnsibleModule(argument_spec=spec, supports_check_mode=True) warnings = list() gather_subset = module.params['gather_subset'] runable_subsets = set() exclude_subsets = set() for subset in gather_subset: if subset == 'all': runable_subsets.update(VALID_SUBSETS) continue if subset.startswith('!'): subset = subset[1:] if subset == 'all': exclude_subsets.update(VALID_SUBSETS) continue exclude = True else: exclude = False if subset not in VALID_SUBSETS: module.fail_json(msg='Bad subset') if exclude: exclude_subsets.add(subset) else: runable_subsets.add(subset) if not runable_subsets: runable_subsets.update(VALID_SUBSETS) runable_subsets.difference_update(exclude_subsets) runable_subsets.add('default') facts = dict() facts['gather_subset'] = list(runable_subsets) instances = list() for key in runable_subsets: instances.append(FACT_SUBSETS[key]()) try: for inst in instances: commands = inst.commands() responses = run_command(module, commands) results = dict(zip(commands, responses)) inst.populate(results) facts.update(inst.facts) except Exception: module.exit_json(out=module.from_json(results)) ansible_facts = dict() for key, value in iteritems(facts): key = 'ansible_net_%s' % key ansible_facts[key] = value module.exit_json(ansible_facts=ansible_facts, warnings=warnings)
def main(): spec = dict(gather_subset=dict(default=['!config'], type='list')) spec.update(iosxr_argument_spec) module = AnsibleModule(argument_spec=spec, supports_check_mode=True) warnings = list() check_args(module, warnings) gather_subset = module.params['gather_subset'] runable_subsets = set() exclude_subsets = set() for subset in gather_subset: if subset == 'all': runable_subsets.update(VALID_SUBSETS) continue if subset.startswith('!'): subset = subset[1:] if subset == 'all': exclude_subsets.update(VALID_SUBSETS) continue exclude = True else: exclude = False if subset not in VALID_SUBSETS: module.fail_json(msg='Bad subset') if exclude: exclude_subsets.add(subset) else: runable_subsets.add(subset) if not runable_subsets: runable_subsets.update(VALID_SUBSETS) runable_subsets.difference_update(exclude_subsets) runable_subsets.add('default') facts = dict() facts['gather_subset'] = list(runable_subsets) instances = list() for key in runable_subsets: instances.append(FACT_SUBSETS[key]()) try: for inst in instances: commands = inst.commands() responses = run_commands(module, commands) results = dict(zip(commands, responses)) inst.populate(results) facts.update(inst.facts) except Exception: module.exit_json(out=module.from_json(results)) ansible_facts = dict() for key, value in iteritems(facts): key = 'ansible_net_%s' % key ansible_facts[key] = value module.exit_json(ansible_facts=ansible_facts, warnings=warnings)
def main(): """main entry point for Ansible module """ argument_spec = dict( rpc=dict(required=True), args=dict(type="dict"), attrs=dict(type="dict"), output=dict(default="xml", choices=["xml", "json", "text"]), ) argument_spec.update(junos_argument_spec) module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=False) warnings = list() result = {"changed": False, "warnings": warnings} rpc = str(module.params["rpc"]).replace("_", "-") if all((module.check_mode, not rpc.startswith("get"))): module.fail_json(msg="invalid rpc for running in check_mode") args = module.params["args"] or {} attrs = module.params["attrs"] or {} xattrs = {"format": module.params["output"]} for key, value in iteritems(attrs): xattrs.update({key: value}) element = Element(module.params["rpc"], xattrs) for key, value in iteritems(args): key = str(key).replace("_", "-") if isinstance(value, list): for item in value: child = SubElement(element, key) if item is not True: child.text = item else: child = SubElement(element, key) if value is not True: child.text = value reply = exec_rpc(module, tostring(element), ignore_warning=False) result["xml"] = tostring(reply) if module.params["output"] == "text": data = reply.find(".//output") result["output"] = data.text.strip() result["output_lines"] = result["output"].split("\n") elif module.params["output"] == "json": result["output"] = module.from_json(reply.text.strip()) else: result["output"] = tostring(reply).split("\n") module.exit_json(**result)
class NitroAPICaller(object): _argument_spec = dict( nsip=dict( fallback=(env_fallback, ['NETSCALER_NSIP']), ), nitro_user=dict( fallback=(env_fallback, ['NETSCALER_NITRO_USER']), ), nitro_pass=dict( fallback=(env_fallback, ['NETSCALER_NITRO_PASS']), no_log=True ), nitro_protocol=dict( choices=['http', 'https'], fallback=(env_fallback, ['NETSCALER_NITRO_PROTOCOL']), default='http' ), validate_certs=dict( default=True, type='bool' ), nitro_auth_token=dict( type='str', no_log=True ), resource=dict(type='str'), name=dict(type='str'), attributes=dict(type='dict'), args=dict(type='dict'), filter=dict(type='dict'), operation=dict( type='str', required=True, choices=[ 'add', 'update', 'get', 'get_by_args', 'get_filtered', 'get_all', 'delete', 'delete_by_args', 'count', 'mas_login', # Actions 'save_config', # Generic action handler 'action', ] ), expected_nitro_errorcode=dict( type='list', default=[0], ), action=dict(type='str'), instance_ip=dict(type='str'), instance_name=dict(type='str'), instance_id=dict(type='str'), ) def __init__(self): self._module = AnsibleModule( argument_spec=self._argument_spec, supports_check_mode=False, ) self._module_result = dict( failed=False, ) # Prepare the http headers according to module arguments self._headers = {} self._headers['Content-Type'] = 'application/json' # Check for conflicting authentication methods have_token = self._module.params['nitro_auth_token'] is not None have_userpass = None not in (self._module.params['nitro_user'], self._module.params['nitro_pass']) login_operation = self._module.params['operation'] == 'mas_login' if have_token and have_userpass: self.fail_module(msg='Cannot define both authentication token and username/password') if have_token: self._headers['Cookie'] = "NITRO_AUTH_TOKEN=%s" % self._module.params['nitro_auth_token'] if have_userpass and not login_operation: self._headers['X-NITRO-USER'] = self._module.params['nitro_user'] self._headers['X-NITRO-PASS'] = self._module.params['nitro_pass'] # Do header manipulation when doing a MAS proxy call if self._module.params['instance_ip'] is not None: self._headers['_MPS_API_PROXY_MANAGED_INSTANCE_IP'] = self._module.params['instance_ip'] elif self._module.params['instance_name'] is not None: self._headers['_MPS_API_PROXY_MANAGED_INSTANCE_NAME'] = self._module.params['instance_name'] elif self._module.params['instance_id'] is not None: self._headers['_MPS_API_PROXY_MANAGED_INSTANCE_ID'] = self._module.params['instance_id'] def edit_response_data(self, r, info, result, success_status): # Search for body in both http body and http data if r is not None: result['http_response_body'] = codecs.decode(r.read(), 'utf-8') elif 'body' in info: result['http_response_body'] = codecs.decode(info['body'], 'utf-8') del info['body'] else: result['http_response_body'] = '' result['http_response_data'] = info # Update the nitro_* parameters according to expected success_status # Use explicit return values from http response or deduce from http status code # Nitro return code in http data result['nitro_errorcode'] = None result['nitro_message'] = None result['nitro_severity'] = None if result['http_response_body'] != '': try: data = self._module.from_json(result['http_response_body']) except ValueError: data = {} result['nitro_errorcode'] = data.get('errorcode') result['nitro_message'] = data.get('message') result['nitro_severity'] = data.get('severity') # If we do not have the nitro errorcode from body deduce it from the http status if result['nitro_errorcode'] is None: # HTTP status failed if result['http_response_data'].get('status') != success_status: result['nitro_errorcode'] = -1 result['nitro_message'] = result['http_response_data'].get('msg', 'HTTP status %s' % result['http_response_data']['status']) result['nitro_severity'] = 'ERROR' # HTTP status succeeded else: result['nitro_errorcode'] = 0 result['nitro_message'] = 'Success' result['nitro_severity'] = 'NONE' def handle_get_return_object(self, result): result['nitro_object'] = [] if result['nitro_errorcode'] == 0: if result['http_response_body'] != '': data = self._module.from_json(result['http_response_body']) if self._module.params['resource'] in data: result['nitro_object'] = data[self._module.params['resource']] else: del result['nitro_object'] def fail_module(self, msg, **kwargs): self._module_result['failed'] = True self._module_result['changed'] = False self._module_result.update(kwargs) self._module_result['msg'] = msg self._module.fail_json(**self._module_result) def main(self): if self._module.params['operation'] == 'add': result = self.add() if self._module.params['operation'] == 'update': result = self.update() if self._module.params['operation'] == 'delete': result = self.delete() if self._module.params['operation'] == 'delete_by_args': result = self.delete_by_args() if self._module.params['operation'] == 'get': result = self.get() if self._module.params['operation'] == 'get_by_args': result = self.get_by_args() if self._module.params['operation'] == 'get_filtered': result = self.get_filtered() if self._module.params['operation'] == 'get_all': result = self.get_all() if self._module.params['operation'] == 'count': result = self.count() if self._module.params['operation'] == 'mas_login': result = self.mas_login() if self._module.params['operation'] == 'action': result = self.action() if self._module.params['operation'] == 'save_config': result = self.save_config() if result['nitro_errorcode'] not in self._module.params['expected_nitro_errorcode']: self.fail_module(msg='NITRO Failure', **result) self._module_result.update(result) self._module.exit_json(**self._module_result) def exit_module(self): self._module.exit_json() def add(self): # Check if required attributes are present if self._module.params['resource'] is None: self.fail_module(msg='NITRO resource is undefined.') if self._module.params['attributes'] is None: self.fail_module(msg='NITRO resource attributes are undefined.') url = '%s://%s/nitro/v1/config/%s' % ( self._module.params['nitro_protocol'], self._module.params['nsip'], self._module.params['resource'], ) data = self._module.jsonify({self._module.params['resource']: self._module.params['attributes']}) r, info = fetch_url( self._module, url=url, headers=self._headers, data=data, method='POST', ) result = {} self.edit_response_data(r, info, result, success_status=201) if result['nitro_errorcode'] == 0: self._module_result['changed'] = True else: self._module_result['changed'] = False return result def update(self): # Check if required attributes are arguments present if self._module.params['resource'] is None: self.fail_module(msg='NITRO resource is undefined.') if self._module.params['name'] is None: self.fail_module(msg='NITRO resource name is undefined.') if self._module.params['attributes'] is None: self.fail_module(msg='NITRO resource attributes are undefined.') url = '%s://%s/nitro/v1/config/%s/%s' % ( self._module.params['nitro_protocol'], self._module.params['nsip'], self._module.params['resource'], self._module.params['name'], ) data = self._module.jsonify({self._module.params['resource']: self._module.params['attributes']}) r, info = fetch_url( self._module, url=url, headers=self._headers, data=data, method='PUT', ) result = {} self.edit_response_data(r, info, result, success_status=200) if result['nitro_errorcode'] == 0: self._module_result['changed'] = True else: self._module_result['changed'] = False return result def get(self): if self._module.params['resource'] is None: self.fail_module(msg='NITRO resource is undefined.') if self._module.params['name'] is None: self.fail_module(msg='NITRO resource name is undefined.') url = '%s://%s/nitro/v1/config/%s/%s' % ( self._module.params['nitro_protocol'], self._module.params['nsip'], self._module.params['resource'], self._module.params['name'], ) r, info = fetch_url( self._module, url=url, headers=self._headers, method='GET', ) result = {} self.edit_response_data(r, info, result, success_status=200) self.handle_get_return_object(result) self._module_result['changed'] = False return result def get_by_args(self): if self._module.params['resource'] is None: self.fail_module(msg='NITRO resource is undefined.') if self._module.params['args'] is None: self.fail_module(msg='NITRO args is undefined.') url = '%s://%s/nitro/v1/config/%s' % ( self._module.params['nitro_protocol'], self._module.params['nsip'], self._module.params['resource'], ) args_dict = self._module.params['args'] args = ','.join(['%s:%s' % (k, args_dict[k]) for k in args_dict]) args = 'args=' + args url = '?'.join([url, args]) r, info = fetch_url( self._module, url=url, headers=self._headers, method='GET', ) result = {} self.edit_response_data(r, info, result, success_status=200) self.handle_get_return_object(result) self._module_result['changed'] = False return result def get_filtered(self): if self._module.params['resource'] is None: self.fail_module(msg='NITRO resource is undefined.') if self._module.params['filter'] is None: self.fail_module(msg='NITRO filter is undefined.') keys = list(self._module.params['filter'].keys()) filter_key = keys[0] filter_value = self._module.params['filter'][filter_key] filter_str = '%s:%s' % (filter_key, filter_value) url = '%s://%s/nitro/v1/config/%s?filter=%s' % ( self._module.params['nitro_protocol'], self._module.params['nsip'], self._module.params['resource'], filter_str, ) r, info = fetch_url( self._module, url=url, headers=self._headers, method='GET', ) result = {} self.edit_response_data(r, info, result, success_status=200) self.handle_get_return_object(result) self._module_result['changed'] = False return result def get_all(self): if self._module.params['resource'] is None: self.fail_module(msg='NITRO resource is undefined.') url = '%s://%s/nitro/v1/config/%s' % ( self._module.params['nitro_protocol'], self._module.params['nsip'], self._module.params['resource'], ) print('headers %s' % self._headers) r, info = fetch_url( self._module, url=url, headers=self._headers, method='GET', ) result = {} self.edit_response_data(r, info, result, success_status=200) self.handle_get_return_object(result) self._module_result['changed'] = False return result def delete(self): if self._module.params['resource'] is None: self.fail_module(msg='NITRO resource is undefined.') if self._module.params['name'] is None: self.fail_module(msg='NITRO resource is undefined.') # Deletion by name takes precedence over deletion by attributes url = '%s://%s/nitro/v1/config/%s/%s' % ( self._module.params['nitro_protocol'], self._module.params['nsip'], self._module.params['resource'], self._module.params['name'], ) r, info = fetch_url( self._module, url=url, headers=self._headers, method='DELETE', ) result = {} self.edit_response_data(r, info, result, success_status=200) if result['nitro_errorcode'] == 0: self._module_result['changed'] = True else: self._module_result['changed'] = False return result def delete_by_args(self): if self._module.params['resource'] is None: self.fail_module(msg='NITRO resource is undefined.') if self._module.params['args'] is None: self.fail_module(msg='NITRO args is undefined.') url = '%s://%s/nitro/v1/config/%s' % ( self._module.params['nitro_protocol'], self._module.params['nsip'], self._module.params['resource'], ) args_dict = self._module.params['args'] args = ','.join(['%s:%s' % (k, args_dict[k]) for k in args_dict]) args = 'args=' + args url = '?'.join([url, args]) r, info = fetch_url( self._module, url=url, headers=self._headers, method='DELETE', ) result = {} self.edit_response_data(r, info, result, success_status=200) if result['nitro_errorcode'] == 0: self._module_result['changed'] = True else: self._module_result['changed'] = False return result def count(self): if self._module.params['resource'] is None: self.fail_module(msg='NITRO resource is undefined.') url = '%s://%s/nitro/v1/config/%s?count=yes' % ( self._module.params['nitro_protocol'], self._module.params['nsip'], self._module.params['resource'], ) r, info = fetch_url( self._module, url=url, headers=self._headers, method='GET', ) result = {} self.edit_response_data(r, info, result) if result['http_response_body'] != '': data = self._module.from_json(result['http_response_body']) result['nitro_errorcode'] = data['errorcode'] result['nitro_message'] = data['message'] result['nitro_severity'] = data['severity'] if self._module.params['resource'] in data: result['nitro_count'] = data[self._module.params['resource']][0]['__count'] self._module_result['changed'] = False return result def action(self): # Check if required attributes are present if self._module.params['resource'] is None: self.fail_module(msg='NITRO resource is undefined.') if self._module.params['attributes'] is None: self.fail_module(msg='NITRO resource attributes are undefined.') if self._module.params['action'] is None: self.fail_module(msg='NITRO action is undefined.') url = '%s://%s/nitro/v1/config/%s?action=%s' % ( self._module.params['nitro_protocol'], self._module.params['nsip'], self._module.params['resource'], self._module.params['action'], ) data = self._module.jsonify({self._module.params['resource']: self._module.params['attributes']}) r, info = fetch_url( self._module, url=url, headers=self._headers, data=data, method='POST', ) result = {} self.edit_response_data(r, info, result, success_status=200) if result['nitro_errorcode'] == 0: self._module_result['changed'] = True else: self._module_result['changed'] = False return result def mas_login(self): url = '%s://%s/nitro/v1/config/login' % ( self._module.params['nitro_protocol'], self._module.params['nsip'], ) login_credentials = { 'login': { 'username': self._module.params['nitro_user'], 'password': self._module.params['nitro_pass'], } } data = 'object=\n%s' % self._module.jsonify(login_credentials) r, info = fetch_url( self._module, url=url, headers=self._headers, data=data, method='POST', ) print(r, info) result = {} self.edit_response_data(r, info, result, success_status=200) if result['nitro_errorcode'] == 0: body_data = self._module.from_json(result['http_response_body']) result['nitro_auth_token'] = body_data['login'][0]['sessionid'] self._module_result['changed'] = False return result def save_config(self): url = '%s://%s/nitro/v1/config/nsconfig?action=save' % ( self._module.params['nitro_protocol'], self._module.params['nsip'], ) data = self._module.jsonify( { 'nsconfig': {}, } ) r, info = fetch_url( self._module, url=url, headers=self._headers, data=data, method='POST', ) result = {} self.edit_response_data(r, info, result, success_status=200) self._module_result['changed'] = False return result
def main(): module = AnsibleModule( argument_spec=dict( xml=dict(type='str', required=False), src=dict(type='path', required=False), datastore=dict(choices=['auto', 'candidate', 'running'], default='auto'), save=dict(type='bool', default=False), # connection arguments host=dict(type='str'), port=dict(type='int', default=830), username=dict(type='str', no_log=True), password=dict(type='str', no_log=True), hostkey_verify=dict(type='bool', default=True), look_for_keys=dict(type='bool', default=True), allow_agent=dict(type='bool', default=True), key_filename=dict(type='path', required=False), ), mutually_exclusive=[('xml', 'src'), ('password', 'key_filename')] ) if not module._socket_path and not HAS_NCCLIENT: module.fail_json(msg='could not import the python library ' 'ncclient required by this module') if (module.params['src']): config_xml = str(module.params['src']) elif module.params['xml']: config_xml = str(module.params['xml']) else: module.fail_json(msg='Option src or xml must be provided') local_connection = module._socket_path is None if not local_connection: m = Connection(module._socket_path) capabilities = module.from_json(m.get_capabilities()) server_capabilities = capabilities.get('server_capabilities') else: nckwargs = dict( host=module.params['host'], port=module.params['port'], hostkey_verify=module.params['hostkey_verify'], allow_agent=module.params['allow_agent'], look_for_keys=module.params['look_for_keys'], username=module.params['username'], password=module.params['password'], key_filename=module.params['key_filename'], ) try: m = ncclient.manager.connect(**nckwargs) server_capabilities = list(m.server_capabilities) except ncclient.transport.errors.AuthenticationError: module.fail_json( msg='authentication failed while connecting to device' ) except Exception as e: module.fail_json(msg='error connecting to the device: %s' % to_native(e), exception=traceback.format_exc()) try: xml.dom.minidom.parseString(config_xml) except Exception as e: module.fail_json(msg='error parsing XML: %s' % to_native(e), exception=traceback.format_exc()) retkwargs = dict() retkwargs['server_capabilities'] = server_capabilities server_capabilities = '\n'.join(server_capabilities) if module.params['datastore'] == 'candidate': if ':candidate' in server_capabilities: datastore = 'candidate' else: if local_connection: m.close_session() module.fail_json( msg=':candidate is not supported by this netconf server' ) elif module.params['datastore'] == 'running': if ':writable-running' in server_capabilities: datastore = 'running' else: if local_connection: m.close_session() module.fail_json( msg=':writable-running is not supported by this netconf server' ) elif module.params['datastore'] == 'auto': if ':candidate' in server_capabilities: datastore = 'candidate' elif ':writable-running' in server_capabilities: datastore = 'running' else: if local_connection: m.close_session() module.fail_json( msg='neither :candidate nor :writable-running are supported by this netconf server' ) else: if local_connection: m.close_session() module.fail_json( msg=module.params['datastore'] + ' datastore is not supported by this ansible module' ) if module.params['save']: if ':startup' not in server_capabilities: module.fail_json( msg='cannot copy <running/> to <startup/>, while :startup is not supported' ) try: changed = netconf_edit_config( m=m, xml=config_xml, commit=True, retkwargs=retkwargs, datastore=datastore, capabilities=server_capabilities, local_connection=local_connection ) if changed and module.params['save']: m.copy_config(source="running", target="startup") except Exception as e: module.fail_json(msg='error editing configuration: %s' % to_native(e), exception=traceback.format_exc()) finally: if local_connection: m.close_session() module.exit_json(changed=changed, **retkwargs)
def main(): """main entry point for execution """ backup_spec = dict( filename=dict(), dir_path=dict(type='path') ) argument_spec = dict( backup=dict(default=False, type='bool'), backup_options=dict(type='dict', options=backup_spec), config=dict(type='str'), commit=dict(type='bool'), replace=dict(type='str'), rollback=dict(type='int'), commit_comment=dict(type='str'), defaults=dict(default=False, type='bool'), multiline_delimiter=dict(type='str'), diff_replace=dict(choices=['line', 'block', 'config']), diff_match=dict(choices=['line', 'strict', 'exact', 'none']), diff_ignore_lines=dict(type='list') ) mutually_exclusive = [('config', 'rollback')] required_one_of = [['backup', 'config', 'rollback']] module = AnsibleModule(argument_spec=argument_spec, mutually_exclusive=mutually_exclusive, required_one_of=required_one_of, supports_check_mode=True) result = {'changed': False} connection = Connection(module._socket_path) capabilities = module.from_json(connection.get_capabilities()) if capabilities: device_operations = capabilities.get('device_operations', dict()) validate_args(module, device_operations) else: device_operations = dict() if module.params['defaults']: if 'get_default_flag' in capabilities.get('rpc'): flags = connection.get_default_flag() else: flags = 'all' else: flags = [] candidate = module.params['config'] candidate = to_text(candidate, errors='surrogate_then_replace') if candidate else None running = connection.get_config(flags=flags) rollback_id = module.params['rollback'] if module.params['backup']: result['__backup__'] = running if candidate or rollback_id or module.params['replace']: try: result.update(run(module, device_operations, connection, candidate, running, rollback_id)) except Exception as exc: module.fail_json(msg=to_text(exc)) module.exit_json(**result)
def main(): """main entry point for execution""" backup_spec = dict(filename=dict(), dir_path=dict(type="path")) argument_spec = dict( backup=dict(default=False, type="bool"), backup_options=dict(type="dict", options=backup_spec), config=dict(type="str"), commit=dict(type="bool"), replace=dict(type="str"), rollback=dict(type="int"), commit_comment=dict(type="str"), defaults=dict(default=False, type="bool"), multiline_delimiter=dict(type="str"), diff_replace=dict(choices=["line", "block", "config"]), diff_match=dict(choices=["line", "strict", "exact", "none"]), diff_ignore_lines=dict(type="list", elements="str"), ) mutually_exclusive = [("config", "rollback")] required_one_of = [["backup", "config", "rollback"]] module = AnsibleModule( argument_spec=argument_spec, mutually_exclusive=mutually_exclusive, required_one_of=required_one_of, supports_check_mode=True, ) result = {"changed": False} connection = Connection(module._socket_path) capabilities = module.from_json(connection.get_capabilities()) if capabilities: device_operations = capabilities.get("device_operations", dict()) validate_args(module, device_operations) else: device_operations = dict() if module.params["defaults"]: if "get_default_flag" in capabilities.get("rpc"): flags = connection.get_default_flag() else: flags = "all" else: flags = [] candidate = module.params["config"] candidate = (to_text(candidate, errors="surrogate_then_replace") if candidate else None) running = connection.get_config(flags=flags) rollback_id = module.params["rollback"] if module.params["backup"]: result["__backup__"] = running if candidate or rollback_id is not None or module.params["replace"]: try: result.update( run( module, device_operations, connection, candidate, running, rollback_id, )) except Exception as exc: module.fail_json(msg=to_text(exc)) module.exit_json(**result)
def main(): # define the available arguments/parameters module_args = dict( name=dict(type='str', required=True), state=dict(type='str', choices=["enabled", "latest", "disabled", "report"], required=True), nextcloud_path=dict(type='path', required=True), app_store_url=dict( type='str', required=False, default="https://apps.nextcloud.com/api/v1/platform/{0}/apps.json" ), version=dict(type='str', required=False, default=None), validate_certs=dict(type='bool', default=True), keep_newer=dict(type='bool', default=False), ) # seed the result dict in the object result = dict(changed=False, platform='', name='', installed=False, enabled=False, version_local='', path_local='', version_remote='', url_remote='', diff={ 'before': '', 'after': '' }) # set empty diff diff_after = '' # AnsibleModule object module = AnsibleModule(argument_spec=module_args, add_file_common_args=True, supports_check_mode=True) app_name = module.params['name'] result['name'] = app_name # requires Python module 'semantic_version' if not semantic_version_found: module.fail_json(msg='The python semantic-version library is required', **result) # requires occ script in Nextcloud path occ_path = os.path.join(module.params['nextcloud_path'], 'occ') if not os.path.isfile(occ_path): module.fail_json(msg='No occ found in nextcloud_path', **result) # get Nextcloud platform out = occ_command(module, occ_path, 'status') result['platform'] = module.from_json(out)['versionstring'] # read in local Nextcloud apps (result['installed'], result['enabled'], result['version_local'], result['path_local']) = app_state_local(module, occ_path, app_name) # get version and URL from app store (result['version_remote'], result['url_remote']) = app_state_store( module, module.params['app_store_url'].format(result['platform']), module.params['version']) if (((module.params['state'] == 'latest' and result['version_local'] != result['version_remote']) or (module.params['state'] == 'enabled' and not result['installed'])) and result['url_remote']): # INSTALL/UPDATE apps_dir = os.path.join(module.params['nextcloud_path'], 'apps') app_archive = app_fetch(module, result['url_remote']) module.params['dest'] = os.path.join(apps_dir, app_name) file_args = module.load_file_common_arguments(module.params) # temporarily disable the app if result['enabled']: if not module.check_mode: out = occ_command(module, occ_path, 'app:disable', app_name, False) result['enabled'] = False result['changed'] = True # install/upgrade the app if not module.check_mode: out = app_unarchive(module, app_archive, apps_dir, file_args) result['installed'] = True result['version_local'] = module.params['version'] result['changed'] = True diff_after = diff_after + '- installed app {0} version {1}\n'.format( app_name, result['version_local']) os.unlink(app_archive) if (module.params['state'] in ['latest', 'enabled'] and not result['enabled']): # ENABLE if not module.check_mode: out = occ_command(module, occ_path, 'app:enable', app_name, False) result['enabled'] = True result['changed'] = True diff_after = diff_after + '- enabled app {0}\n'.format(app_name) elif (module.params['state'] == 'disabled' and result['enabled']): # DISABLE if not module.check_mode: out = occ_command(module, occ_path, 'app:disable', app_name, False) result['enabled'] = False result['version_local'] = '' result['changed'] = True diff_after = diff_after + '- disabled app {0}\n'.format(app_name) result['diff']['after'] = diff_after module.exit_json(**result)