Server IP : 85.214.239.14 / Your IP : 18.189.182.15 Web Server : Apache/2.4.62 (Debian) System : Linux h2886529.stratoserver.net 4.9.0 #1 SMP Tue Jan 9 19:45:01 MSK 2024 x86_64 User : www-data ( 33) PHP Version : 7.4.18 Disable Function : pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,pcntl_unshare, MySQL : OFF | cURL : OFF | WGET : ON | Perl : ON | Python : ON | Sudo : ON | Pkexec : OFF Directory : /lib/python3/dist-packages/ansible_collections/community/sap/plugins/modules/ |
Upload File : |
#!/usr/bin/python # -*- coding: utf-8 -*- # Copyright: (c) 2021, Rainer Leber <rainerleber@gmail.com> <rainer.leber@sva.de> # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) from __future__ import (absolute_import, division, print_function) __metaclass__ = type DOCUMENTATION = r''' --- module: sap_snote short_description: This module will upload and (de)implements C(SNOTES) in a SAP S4HANA environment. version_added: "1.0.0" description: - The C(sap_snote) module depends on C(pyrfc) Python library (version 2.4.0 and upwards). Depending on distribution you are using, you may need to install additional packages to have these available. - This module will use the Function Group C(SCWB_API). - The C(TMS) must be configured at first. - Integrating SNOTES cannot be done via C(DDIC)- or C(SAP*)-User. options: state: description: - The decision what to do with the SNOTE. - Could be C('present'), C('absent') default: 'present' choices: - 'present' - 'absent' required: false type: str conn_username: description: The required username for the SAP system. required: true type: str conn_password: description: The required password for the SAP system. required: true type: str host: description: The required host for the SAP system. Can be either an FQDN or IP Address. required: true type: str sysnr: description: - The system number of the SAP system. - You must quote the value to ensure retaining the leading zeros. required: false default: '01' type: str client: description: - The client number to connect to. - You must quote the value to ensure retaining the leading zeros. required: false default: '000' type: str snote_path: description: - The path to the extracted SNOTE txt file. - The File could be extracted from SAR package. - If C(snote_path) is not provided, the C(snote) parameter must be defined. - The SNOTE txt file must be at a place where the SAP System is authorized for. For example C(/usr/sap/trans/files). required: false type: str snote: description: - With the C(snote) paramter only implementation and deimplementation will work. - Upload SNOTES to the System is only available if C(snote_path) is provided. required: false type: str requirements: - pyrfc >= 2.4.0 author: - Rainer Leber (@rainerleber) ''' EXAMPLES = r''' - name: test snote module hosts: localhost tasks: - name: implement SNOTE community.sap.sap_snote: conn_username: 'DDIC' conn_password: 'Passwd1234' host: 192.168.1.100 sysnr: '01' client: '000' state: present snote_path: /usr/sap/trans/tmp/0002949148.txt - name: test snote module without path hosts: localhost tasks: - name: deimplement SNOTE community.sap.sap_snote: conn_username: 'DDIC' conn_password: 'Passwd1234' host: 192.168.1.100 sysnr: '01' client: '000' state: absent snote: 0002949148 ''' RETURN = r''' msg: description: A small execution description. type: str returned: always sample: 'SNOTE 000298026 implemented.' out: description: A complete description of the SNOTE implementation. If this is available. type: list elements: dict returned: always sample: '{ "RETURN": [{"ES_MSG": { "MSGNO": "000", "MSGTY": "", "MSGTXT": "", "MSGV1": "" }, "ET_MSG": [], "EV_RC": 0, "ET_MISSING_NOTES": [], "IT_FILENAME": [{"FILENAME": "/usr/sap/trans/tmp/0002980265.txt"}], "IT_NOTES": [{"NUMM": "0002980265", "VERSNO": "0000"}] }]}' ''' from ansible.module_utils.basic import AnsibleModule, missing_required_lib from os import path as os_path import traceback try: from pyrfc import Connection except ImportError: HAS_PYRFC_LIBRARY = False ANOTHER_LIBRARY_IMPORT_ERROR = traceback.format_exc() else: HAS_PYRFC_LIBRARY = True def call_rfc_method(connection, method_name, kwargs): # PyRFC call function return connection.call(method_name, **kwargs) def check_implementation(conn, snote): check_implemented = call_rfc_method(conn, 'SCWB_API_GET_NOTES_IMPLEMENTED', {}) for snote_list in check_implemented['ET_NOTES_IMPL']: if snote in snote_list['NUMM']: return True return False def run_module(): module = AnsibleModule( argument_spec=dict( state=dict(default='present', choices=['absent', 'present']), conn_username=dict(type='str', required=True), conn_password=dict(type='str', required=True, no_log=True), host=dict(type='str', required=True), sysnr=dict(type='str', default="01"), client=dict(type='str', default="000"), snote_path=dict(type='str', required=False), snote=dict(type='str', required=False), ), required_one_of=[('snote_path', 'snote')], supports_check_mode=False, ) result = dict(changed=False, msg='', out={}, error='') raw = "" post_check = False params = module.params state = params['state'] conn_username = (params['conn_username']).upper() conn_password = params['conn_password'] host = params['host'] sysnr = (params['sysnr']).zfill(2) client = params['client'] path = params['snote_path'] snote = params['snote'] if not HAS_PYRFC_LIBRARY: module.fail_json( msg=missing_required_lib('pyrfc'), exception=ANOTHER_LIBRARY_IMPORT_ERROR) if conn_username == "DDIC" or conn_username == "SAP*": result['msg'] = 'User C(DDIC) or C(SAP*) not allowed for this operation.' module.fail_json(**result) # basic RFC connection with pyrfc try: conn = Connection(user=conn_username, passwd=conn_password, ashost=host, sysnr=sysnr, client=client) except Exception as err: result['error'] = str(err) result['msg'] = 'Something went wrong connecting to the SAP system.' module.fail_json(**result) # pre evaluation of parameters if path is not None: if path.endswith('.txt'): # splits snote number from path and txt extension snote = os_path.basename(os_path.normpath(path)).split('.')[0] else: result['msg'] = 'The path must include the extracted snote file and ends with txt.' module.fail_json(**result) pre_check = check_implementation(conn, snote) if state == "absent" and pre_check: raw = call_rfc_method(conn, 'SCWB_API_NOTES_DEIMPLEMENT', {'IT_NOTES': [snote]}) if state == "present" and not pre_check: if path: raw_upload = call_rfc_method(conn, 'SCWB_API_UPLOAD_NOTES', {'IT_FILENAME': [path], 'IT_NOTES': [snote]}) if raw_upload['EV_RC'] != 0: result['out'] = raw_upload result['msg'] = raw_upload['ES_MSG']['MSGTXT'] module.fail_json(**result) raw = call_rfc_method(conn, 'SCWB_API_NOTES_IMPLEMENT', {'IT_NOTES': [snote]}) queued = call_rfc_method(conn, 'SCWB_API_CINST_QUEUE_GET', {}) if queued['ET_MANUAL_ACTIVITIES']: raw = call_rfc_method(conn, 'SCWB_API_CONFIRM_MAN_ACTIVITY', {}) if raw: if raw['EV_RC'] == 0: post_check = check_implementation(conn, snote) if post_check and state == "present": result['changed'] = True result['msg'] = 'SNOTE "{0}" implemented.'.format(snote) if not post_check and state == "absent": result['changed'] = True result['msg'] = 'SNOTE "{0}" deimplemented.'.format(snote) else: result['msg'] = "Something went wrong." module.fail_json(**result) result['out'] = raw else: result['msg'] = "Nothing to do." module.exit_json(**result) def main(): run_module() if __name__ == '__main__': main()