From 0ee7de2f3e61cb8c007d3e7207e515b14d30e08e Mon Sep 17 00:00:00 2001 From: sean-freeman <1815807+sean-freeman@users.noreply.github.com> Date: Wed, 10 Jan 2024 21:07:05 +0000 Subject: [PATCH 1/2] sap_rfc: overhaul of structure --- roles/sap_rfc/README.md | 10 +- roles/sap_rfc/defaults/main.yml | 27 +++- roles/sap_rfc/meta/main.yml | 4 +- roles/sap_rfc/tasks/main.yml | 49 ++++++-- roles/sap_rfc/tasks/python_pyrfc_discover.yml | 1 - roles/sap_rfc/tasks/python_pyrfc_init.yml | 70 ----------- roles/sap_rfc/tasks/setup/nwrfcsdk_init.yml | 116 ++++++++++++++++++ roles/sap_rfc/tasks/setup/python_init.yml | 41 +++++++ 8 files changed, 225 insertions(+), 93 deletions(-) delete mode 100644 roles/sap_rfc/tasks/python_pyrfc_discover.yml delete mode 100644 roles/sap_rfc/tasks/python_pyrfc_init.yml create mode 100644 roles/sap_rfc/tasks/setup/nwrfcsdk_init.yml create mode 100644 roles/sap_rfc/tasks/setup/python_init.yml diff --git a/roles/sap_rfc/README.md b/roles/sap_rfc/README.md index a6da372..7ead9d6 100644 --- a/roles/sap_rfc/README.md +++ b/roles/sap_rfc/README.md @@ -1,6 +1,6 @@ # sap_rfc Ansible Role -The sap_rfc Ansible Role executes an SAP Remote Function Call (RFC), and performs setup as necessary ([`PyRFC`](https://github.com/SAP/PyRFC) open source by SAP, and [`SAP NWRFC SDK`](https://support.sap.com/en/product/connectors/nwrfcsdk.html)). +The sap_rfc Ansible Role executes an SAP Remote Function Call (RFC) from a server-side host with connectivity to the SAP System host/s, and performs setup as necessary ([`PyRFC`](https://github.com/SAP/PyRFC) open source by SAP, and [`SAP NWRFC SDK`](https://support.sap.com/en/product/connectors/nwrfcsdk.html)). ## Ansible Role Overview @@ -8,7 +8,7 @@ The sap_rfc Ansible Role uses: - the Ansible Module `sap_pyrfc` from the Ansible Collection `sap_libs`, which leverages the open-source [`PyRFC`](https://github.com/SAP/PyRFC) bindings for the proprietary [`SAP NWRFC SDK`](https://support.sap.com/en/product/connectors/nwrfcsdk.html). - the Ansible Module `software_center_download` from the Ansible Collection `sap_launchpad`, which on first-run is used to download the [`SAP NWRFC SDK`](https://support.sap.com/en/product/connectors/nwrfcsdk.html). -Appropriate target SAP System user authorizations are required for the execute of the RFCs, and on first-run to obtain the [`SAP NWRFC SDK`](https://support.sap.com/en/product/connectors/nwrfcsdk.html) an SAP User ID with download privileges is required. +Appropriate target SAP System user authorizations are required for the execution of the RFCs, and on first-run to obtain the [`SAP NWRFC SDK`](https://support.sap.com/en/product/connectors/nwrfcsdk.html) an SAP User ID with download privileges is required. The Ansible Role does not contain any system-altering RFCs by default when executed. @@ -60,7 +60,7 @@ These RFC parameter data elements are mapped to the equivilant Python data type `Ansible Task code example for data element:` ```yaml -target_parameters: +sap_rfc_target_parameters: VAR: 'ECHO' ``` @@ -71,7 +71,7 @@ target_parameters: `Ansible Task code example for ABAP Struture:` ```yaml -target_parameters: +sap_rfc_target_parameters: IMPORTSTRUCT: RFCFLOAT: 1.1 RFCCHAR1: 'A' @@ -84,7 +84,7 @@ target_parameters: `Ansible Task code example for ABAP Table:` ```yaml -target_parameters: +sap_rfc_target_parameters: RFCTABLE: - COLUMN0: SAP - COLUMN1: 1.23 diff --git a/roles/sap_rfc/defaults/main.yml b/roles/sap_rfc/defaults/main.yml index ab5aa5f..8d9da29 100644 --- a/roles/sap_rfc/defaults/main.yml +++ b/roles/sap_rfc/defaults/main.yml @@ -1,8 +1,10 @@ -#pyrfc_first_run: true +--- -#sap_nwrfc_sdk: nwrfc750P_10-70002752.zip +# sap_rfc_first_run_download_sap_user_id: "" +# sap_rfc_first_run_download_sap_user_password: "" +sap_rfc_first_run_download_path: /software -#target_connection: +#sap_rfc_target_connection: # ashost: s4hana.poc.cloud # sysid: TDT # sysnr: "01" @@ -15,7 +17,22 @@ # gwhost: gateway.poc.cloud # ghserv: gateway.poc.cloud -target_function: STFC_CONNECTION +sap_rfc_target_function: STFC_CONNECTION -target_parameters: +sap_rfc_target_parameters: REQUTEXT: "Hello SAP!" + + +# Override default for detected CPU Architecture (x86_64, ppc64le) +# Contains /usr/local/sap/nwrfcsdk/lib with libsapnwrfc.so , libicuuc.so.50 , libicudata.so.50 , libicui18n.so.50 , libsapucum.so +# Contains /usr/local/sap/nwrfcsdk/include with sapdecf.h , sapnwrfc.h , sapucrfc.h +# sap_rfc_first_run_download_nwrfc_sdk: "" # 7.50 x86_64 = nwrfc750P_12-70002752.zip , ppc64le = nwrfc750P_12-70002761.zip + + +# NOT USED: +# May cause errors with additional dependency libs not available in the LD_LIBRARY_PATH '/usr/local/sap/nwrfcsdk/lib' +# (e.g. libicuuc65.so, libicudata65.so, libicui18n65.so) +# Not recommended as per SAP Note 3384574 - SAP NW RFC SDK 7.50 hotfix installation +# Therefore Ansible Tasks code exists, but commented-out +# sap_rfc_first_run_download_sapcar: "" # x86_64 = SAPCAR_1115-70006178.EXE , ppc64le = SAPCAR_1115-70006238.EXE +# sap_rfc_first_run_download_nwrfc_sdk_patch: "" # 7.93 Backwards Compatible x86_64 = sapnwrfc_69-70007807.sar , ppc64le = sapnwrfc_69-70007832.sar diff --git a/roles/sap_rfc/meta/main.yml b/roles/sap_rfc/meta/main.yml index 2090cd9..645215f 100644 --- a/roles/sap_rfc/meta/main.yml +++ b/roles/sap_rfc/meta/main.yml @@ -14,5 +14,5 @@ galaxy_info: dependencies: [] # List your role dependencies here, one per line. Be sure to remove the '[]' above, collections: -- community.sap_libs -- community.sap_launchpad + - community.sap_libs + - community.sap_launchpad diff --git a/roles/sap_rfc/tasks/main.yml b/roles/sap_rfc/tasks/main.yml index ad26b1b..ccf15c2 100644 --- a/roles/sap_rfc/tasks/main.yml +++ b/roles/sap_rfc/tasks/main.yml @@ -1,18 +1,47 @@ --- -- name: Initial install of Python altinstall for PyRFC - ansible.builtin.include_tasks: python_pyrfc_init.yml - when: pyrfc_first_run | bool -- name: Discover Python altinstall for PyRFC - ansible.builtin.include_tasks: python_pyrfc_discover.yml - when: not pyrfc_first_run | bool +- name: Identify SAP NW RFC Library home directory + ansible.builtin.find: + paths: /usr/local/sap + recurse: true + file_type: directory + patterns: include + register: __sap_rfc_nwrfc_home + +- name: Identify SAP NW RFC Library compiled shared library (libsapnwrfc.so) + ansible.builtin.find: + paths: /usr/local/sap/nwrfcsdk + recurse: true + file_type: file + patterns: libsapnwrfc.so + register: __sap_rfc_nwrfc_lib + +- name: Identify Python virtual environment for sap_rfc Ansible Role + ansible.builtin.stat: + path: ~/env/pyrfc_env + register: __sap_rfc_python_virtual_env + +- name: Set fact based on identified SAP NW RFC Library + ansible.builtin.set_fact: + __sap_rfc_first_run: "{{ true if ((__sap_rfc_nwrfc_home.files | length) == 0 or (__sap_rfc_nwrfc_lib.files | length) == 0) else false }}" + +- name: Initial install of SAP NW RFC SDK Library + ansible.builtin.include_tasks: setup/nwrfcsdk_init.yml + when: __sap_rfc_first_run | bool + +- name: Initial install of Python virtual environment for PyRFC + ansible.builtin.include_tasks: setup/python_init.yml + when: (__sap_rfc_first_run | bool) or (not __sap_rfc_python_virtual_env.stat.exists) # Use Ansible Task block to call sap_pyrfc Ansible Module in the Ansible Collection for sap_libs # RFC call using variables set by the Ansible Playbook when calling this Ansible Role - name: Execute Ansible Module to call PyRFC using the virtualenv Python3 - community.sap_libs.sap_pyrfc: - function: "{{ target_function }}" - parameters: "{{ target_parameters }}" - connection: "{{ target_connection }}" + environment: + SAPNWRFC_HOME: "{{ __sap_rfc_nwrfc_home.files[0].path | dirname }}" + LD_LIBRARY_PATH: "$LD_LIBRARY_PATH:$SAPNWRFC_HOME/lib" vars: ansible_python_interpreter: ~/env/pyrfc_env/bin/python3 + community.sap_libs.sap_pyrfc: + function: "{{ sap_rfc_target_function }}" + parameters: "{{ sap_rfc_target_parameters }}" + connection: "{{ sap_rfc_target_connection }}" diff --git a/roles/sap_rfc/tasks/python_pyrfc_discover.yml b/roles/sap_rfc/tasks/python_pyrfc_discover.yml deleted file mode 100644 index ed97d53..0000000 --- a/roles/sap_rfc/tasks/python_pyrfc_discover.yml +++ /dev/null @@ -1 +0,0 @@ ---- diff --git a/roles/sap_rfc/tasks/python_pyrfc_init.yml b/roles/sap_rfc/tasks/python_pyrfc_init.yml deleted file mode 100644 index 166ce2c..0000000 --- a/roles/sap_rfc/tasks/python_pyrfc_init.yml +++ /dev/null @@ -1,70 +0,0 @@ ---- -# Dependency on Ansible Role for SAP Launchpad -# - collections: -# community.sap_launchpad - -- name: Create directories if does not exist - ansible.builtin.file: - path: "{{ item }}" - state: directory - mode: "0755" - with_items: - - "/software" - - "/usr/local/sap" - -- name: Install Python package manager pip3, and compiler/library for C and C++ - ansible.builtin.yum: - name: - - python3-pip - - gcc - - glibc - - gcc-c++ - - libstdc++ - state: present - -- name: Install virtualenv to system Python - ansible.builtin.pip: - name: - - virtualenv - -- name: Create virtualenv for python3, install dependencies to virtualenv. Do not inherit system Python modules - ansible.builtin.pip: - name: - - cython - - wheel - - pytest - - sphinx - virtualenv: ~/env/pyrfc_env - virtualenv_command: virtualenv - virtualenv_python: python3 - -# Use task block to call Ansible Module in the Ansible Collection for sap_launchpad -- name: Execute Ansible Module to download SAP software - community.sap_launchpad.software_center_download: - suser_id: "{{ suser_id }}" - suser_password: "{{ suser_password }}" - softwarecenter_search_query: "{{ sap_nwrfc_sdk }}" - dest: "/software" - -- name: Discover zip of the SAP NWRFC SDK on target host - ansible.builtin.find: - paths: "/software" - recurse: true - patterns: "nwrfc*.zip" - register: __sap_nwrfc_sdk - -- name: Extract zip of the SAP NWRFC SDK on target host - ansible.builtin.unarchive: - remote_src: true - src: "{{ __sap_nwrfc_sdk.files[0].path }}" - dest: /usr/local/sap - -- name: Install pyrfc to virtualenv on target host. Do not inherit system Python modules - environment: - SAPNWRFC_HOME: /usr/local/sap/nwrfcsdk - ansible.builtin.pip: - name: - - pyrfc - virtualenv: ~/env/pyrfc_env - virtualenv_command: virtualenv - virtualenv_python: python3 diff --git a/roles/sap_rfc/tasks/setup/nwrfcsdk_init.yml b/roles/sap_rfc/tasks/setup/nwrfcsdk_init.yml new file mode 100644 index 0000000..fe88216 --- /dev/null +++ b/roles/sap_rfc/tasks/setup/nwrfcsdk_init.yml @@ -0,0 +1,116 @@ +--- + +- name: Set fact x86_64 sap_rfc_first_run_download_nwrfc_sdk + ansible.builtin.set_fact: + sap_rfc_first_run_download_nwrfc_sdk: "nwrfc750P_12-70002752.zip" + when: ansible_architecture == "x86_64" + +- name: Set fact x86_64 sap_rfc_first_run_download_nwrfc_sdk + ansible.builtin.set_fact: + sap_rfc_first_run_download_nwrfc_sdk: "nwrfc750P_12-70002761.zip" + when: ansible_architecture == "ppc64le" + +- name: Create directories if does not exist + ansible.builtin.file: + path: "{{ item }}" + state: directory + mode: "0755" + loop: + - "{{ sap_rfc_first_run_download_path }}" + - "/usr/local/sap" + - "/usr/local/sap/nwrfcsdk" + # - "/tmp/nwrfcsdk_patch_extract" + +# Use task block to call Ansible Module in the Ansible Collection for sap_launchpad +- name: Execute Ansible Module to download SAP software + community.sap_launchpad.software_center_download: + suser_id: "{{ sap_rfc_first_run_download_sap_user_id }}" + suser_password: "{{ sap_rfc_first_run_download_sap_user_password }}" + softwarecenter_search_query: "{{ item }}" + dest: "{{ sap_rfc_first_run_download_path }}" + loop: + - "{{ sap_rfc_first_run_download_nwrfc_sdk }}" + # - "{{ sap_rfc_first_run_download_sapcar }}" + # - "{{ sap_rfc_first_run_download_nwrfc_sdk_patch }}" + +- name: Discover zip of the SAP NWRFC SDK (7.5x Original) on target host + ansible.builtin.find: + paths: "{{ sap_rfc_first_run_download_path }}" + recurse: true + patterns: "nwrfc*.zip" + register: __sap_rfc_nwrfc_sdk_zip + +- name: Extract zip of the SAP NWRFC SDK (7.5x) on target host + ansible.builtin.unarchive: + remote_src: true + src: "{{ __sap_rfc_nwrfc_sdk_zip.files[0].path }}" + dest: /usr/local/sap # ZIP contains nwrfcsdk subdirectory + when: __sap_rfc_nwrfc_sdk_zip.files | length > 0 + +# - name: Discover SAR of the SAP NWRFC SDK Patch on target host +# ansible.builtin.find: +# paths: "{{ sap_rfc_first_run_download_path }}" +# recurse: true +# patterns: "sapnwrfc_*.sar" +# register: __sap_rfc_nwrfc_sdk_sar + +# - name: Discover SAPCAR on target host +# ansible.builtin.find: +# paths: "{{ sap_rfc_first_run_download_path }}" +# recurse: true +# patterns: "SAPCAR*" +# register: __sap_rfc_sapcar_exe + +# - name: Extract SAR of the SAP NWRFC SDK Patch on target host +# ansible.builtin.shell: | +# {{ __sap_rfc_sapcar_exe.files[0].path }} \ +# -R /tmp/nwrfcsdk_patch_extract \ +# -xvf "{{ __sap_rfc_nwrfc_sdk_sar.files[0].path }}" +# when: __sap_rfc_nwrfc_sdk_sar.files | length > 0 + +# - name: Find patched compiled shared library (libsapnwrfc.so) +# ansible.builtin.find: +# paths: /tmp/nwrfcsdk_patch_extract +# recurse: true +# patterns: libsapnwrfc.so +# register: __sap_rfc_nwrfc_lib_patch + +- name: Find compiled shared library (libsapnwrfc.so) + ansible.builtin.find: + paths: /usr/local/sap/nwrfcsdk + recurse: true + patterns: libsapnwrfc.so + register: __sap_rfc_nwrfc_lib + +# - name: Copy patched compiled shared library (libsapnwrfc.so) to replace original +# ansible.builtin.copy: +# backup: false # Otherwise ldconfig will identify multiple copies of libsapnwrfc.so +# remote_src: true +# mode: 755 +# src: "{{ __sap_rfc_nwrfc_lib_patch.files[0].path }}" +# dest: "{{ __sap_rfc_nwrfc_lib.files[0].path }}" + +# - name: Create ld.so.conf configuration file with path to compiled shared library (libsapnwrfc.so) +# ansible.builtin.copy: +# dest: /etc/ld.so.conf.d/nwrfcsdk.conf +# mode: '0444' +# content: | +# # include nwrfcsdk +# {{ __sap_rfc_nwrfc_lib.files[0].path | dirname }} +# # include /usr/sap (e.g. libstdc++.so.6) +# /usr/sap/lib + +- name: Reload system-wide library paths (ldconfig) + ansible.builtin.shell: ldconfig + +- name: Ensure compiled shared library (libsapnwrfc.so) is registered as system-wide library + ansible.builtin.shell: ldconfig -p | grep sapnwrfc + register: __sap_rfc_nwrfc_lib_discover_path + +- name: Identify SAP NW RFC Library home directory + ansible.builtin.find: + paths: /usr/local/sap + recurse: true + file_type: directory + patterns: include + register: __sap_rfc_nwrfc_home diff --git a/roles/sap_rfc/tasks/setup/python_init.yml b/roles/sap_rfc/tasks/setup/python_init.yml new file mode 100644 index 0000000..824e597 --- /dev/null +++ b/roles/sap_rfc/tasks/setup/python_init.yml @@ -0,0 +1,41 @@ +--- + +# PyRFC v2.7.0 dropped support for CPython 3.6 (OS System Python version), use CPython 3.9 instead +- name: Install Python package manager pip3, and compiler/library for C and C++ + ansible.builtin.package: + name: + - python39 + - python39-pip + - python39-wheel + - python39-devel # Required for PyRFC compile with GCC + - gcc + - glibc + - gcc-c++ + - libstdc++ + state: present + +- name: Install virtualenv to system Python + ansible.builtin.pip: + name: + - virtualenv + +- name: Create virtualenv for python3, install dependencies to virtualenv. Do not inherit system Python modules + ansible.builtin.pip: + name: + - cython + - wheel + - pytest + - sphinx + virtualenv: ~/env/pyrfc_env + virtualenv_command: virtualenv + virtualenv_python: python3.9 + +- name: Install pyrfc to virtualenv on target host. Do not inherit system Python modules + environment: + SAPNWRFC_HOME: "{{ __sap_rfc_nwrfc_home.files[0].path | dirname }}" + ansible.builtin.pip: + name: + - pyrfc + virtualenv: ~/env/pyrfc_env + virtualenv_command: virtualenv + virtualenv_python: python3.9 From b38e6d1695fe1edb3a8cdb9f1fa23b328a3448b9 Mon Sep 17 00:00:00 2001 From: sean-freeman <1815807+sean-freeman@users.noreply.github.com> Date: Wed, 10 Jan 2024 21:09:22 +0000 Subject: [PATCH 2/2] collection: legacy syntax fixes --- roles/sap_control/tasks/functions/restart_sapstartsrv.yml | 4 ++-- roles/sap_control/tasks/functions/sapstartsrv.yml | 2 +- roles/sap_control/tasks/sapcontrol.yml | 1 - roles/sap_profile_update/tasks/main.yml | 4 ++-- roles/sap_rhsm/tasks/rhsm_register.yml | 2 -- 5 files changed, 5 insertions(+), 8 deletions(-) diff --git a/roles/sap_control/tasks/functions/restart_sapstartsrv.yml b/roles/sap_control/tasks/functions/restart_sapstartsrv.yml index a53c76a..8ea6558 100644 --- a/roles/sap_control/tasks/functions/restart_sapstartsrv.yml +++ b/roles/sap_control/tasks/functions/restart_sapstartsrv.yml @@ -13,7 +13,7 @@ # Stop sapstartsrv - name: SAPstartsrv - Stop sapstartsrv {{ passed_sap_sid }}-{{ passed_sap_nr }} ansible.builtin.shell: | - source ~/.profile && cdexe; sapcontrol -nr {{ passed_sap_nr }} -function StopService {{ passed_sap_sid }} + source ~/.profile ; sapcontrol -nr {{ passed_sap_nr }} -function StopService {{ passed_sap_sid }} args: executable: /bin/bash become: true @@ -25,7 +25,7 @@ # Start sapstartsrv - name: SAPstartsrv - Start sapstartsrv {{ passed_sap_sid }}-{{ passed_sap_nr }} ansible.builtin.shell: | - source ~/.profile && cdexe; sapcontrol -nr {{ passed_sap_nr }} -function StartService {{ passed_sap_sid }} + source ~/.profile ; sapcontrol -nr {{ passed_sap_nr }} -function StartService {{ passed_sap_sid }} args: executable: /bin/bash become: true diff --git a/roles/sap_control/tasks/functions/sapstartsrv.yml b/roles/sap_control/tasks/functions/sapstartsrv.yml index 8f7e037..9f30959 100644 --- a/roles/sap_control/tasks/functions/sapstartsrv.yml +++ b/roles/sap_control/tasks/functions/sapstartsrv.yml @@ -6,7 +6,7 @@ # Check sapstartsrv - name: SAPstartsrv - Check sapstartsrv ansible.builtin.shell: | - source ~/.profile && cdexe; sapcontrol -nr {{ passed_sap_nr }} -function GetSystemInstanceList + source ~/.profile ; sapcontrol -nr {{ passed_sap_nr }} -function GetSystemInstanceList args: executable: /bin/bash become: true diff --git a/roles/sap_control/tasks/sapcontrol.yml b/roles/sap_control/tasks/sapcontrol.yml index 77b7d10..af3cda8 100644 --- a/roles/sap_control/tasks/sapcontrol.yml +++ b/roles/sap_control/tasks/sapcontrol.yml @@ -17,7 +17,6 @@ source ~/.profile && sapcontrol -nr {{ passed_sap_nr }} -function {{ vars['sap_control_' + funct_type] }} args: executable: /bin/bash - warn: false become: true become_user: "{{ passed_sap_sid | lower }}adm" register: sapcontrol_status diff --git a/roles/sap_profile_update/tasks/main.yml b/roles/sap_profile_update/tasks/main.yml index d10cbd6..1a3009b 100644 --- a/roles/sap_profile_update/tasks/main.yml +++ b/roles/sap_profile_update/tasks/main.yml @@ -3,14 +3,14 @@ - name: SAP Profile Update - Get Instance Profile ansible.builtin.shell: | set -o pipefail - source ~/.profile && cdexe; sapcontrol -nr {{ sap_update_profile_instance_nr }} -function ParameterValue SAPPROFILE | grep profile + source ~/.profile ; sapcontrol -nr {{ sap_update_profile_instance_nr }} -function ParameterValue SAPPROFILE | grep profile args: executable: /bin/bash become: true become_user: "{{ sap_update_profile_sid | lower }}adm" register: get_instance_profile -- name: setup facts +- name: SAP Profile Update - Setup facts ansible.builtin.set_fact: sap_update_profile_default_profile_file_path: "/sapmnt/{{ sap_update_profile_sid }}/profile/DEFAULT.PFL" sap_update_profile_instance_profile_file_path: "{{ get_instance_profile.stdout }}" diff --git a/roles/sap_rhsm/tasks/rhsm_register.yml b/roles/sap_rhsm/tasks/rhsm_register.yml index 6be6876..45dfc4d 100644 --- a/roles/sap_rhsm/tasks/rhsm_register.yml +++ b/roles/sap_rhsm/tasks/rhsm_register.yml @@ -42,8 +42,6 @@ - name: Yum clean all ansible.builtin.command: "yum clean all" - args: - warn: false - name: Yum search sap- ansible.builtin.command: "yum -y search sap-"