From d1758f1cf5d471bd4b4ef74dedd2d142a32db7da Mon Sep 17 00:00:00 2001 From: sean-freeman <1815807+sean-freeman@users.noreply.github.com> Date: Thu, 3 Aug 2023 23:33:06 +0100 Subject: [PATCH 1/6] docs: readme updates --- README.md | 30 ++++++++++++++++++------------ docs/EXEC_EXAMPLES.md | 20 ++++++++++---------- 2 files changed, 28 insertions(+), 22 deletions(-) diff --git a/README.md b/README.md index 4efc65b..721be07 100644 --- a/README.md +++ b/README.md @@ -31,19 +31,9 @@ Within this Ansible Collection, there are various Ansible Modules. | [sap_launchpad.maintenance_planner_files](./docs/module_maintenance_planner_files.md) | maintenance planner files retrieval | | [sap_launchpad.maintenance_planner_stack_xml_download](./docs/module_maintenance_planner_stack_xml_download.md) | maintenance planner stack xml download | -## Execution examples +## Execution -There are various methods to execute the Ansible Collection, dependant on the use case. For more information, see [Execution examples with code samples](./docs/EXEC_EXAMPLES.md) and the summary below: - -| Execution Scenario | Use Case | Target | -| --- | --- | --- | -| Ansible Playbook
-> source Ansible Collection
-> execute Ansible Task
--> run Ansible Module
---> run Python/Bash Functions | Simple executions with a few activities | Localhost or Remote | -| Ansible Playbook
-> source Ansible Collection
-> execute Ansible Task
--> run Ansible Role
---> run Ansible Module
----> run Python/Bash Functions
--> run Ansible Role
---> ... | Complex executions with various interlinked activities;
run in parallel or sequentially | Localhost or Remote | -| Python/Bash Functions | Simple testing or non-Ansible use cases | Localhost | - -## Requirements, Dependencies and Testing - -### SAP User ID credentials +### Credentials - SAP User ID SAP software installation media must be obtained from SAP directly, and requires valid license agreements with SAP in order to access these files. @@ -55,6 +45,22 @@ When an SAP User ID (e.g. S-User) is enabled with and part of an SAP Universal I In addition, if a SAP Universal ID is used then the recommendation is to check and reset the SAP User ID ‘Account Password’ in the [SAP Universal ID Account Manager](https://account.sap.com/manage/accounts), which will help to avoid any potential conflicts. +For further information regarding connection errors, please see the FAQ section [Errors with prefix 'SAP SSO authentication failed - '](#errors-with-prefix-sap-sso-authentication-failed---). + +### Execution examples + +There are various methods to execute the Ansible Collection, dependant on the use case. For more information, see [Execution examples with code samples](./docs/EXEC_EXAMPLES.md) and the summary below: + +| Execution Scenario | Use Case | Target | +| --- | --- | --- | +| Ansible Playbook
-> source Ansible Collection
-> execute Ansible Task
--> run Ansible Module
---> run Python/Bash Functions | Simple executions with a few activities | Localhost or Remote | +| Ansible Playbook
-> source Ansible Collection
-> execute Ansible Task
--> run Ansible Role
---> run Ansible Module
----> run Python/Bash Functions
--> run Ansible Role
---> ... | Complex executions with various interlinked activities;
run in parallel or sequentially | Localhost or Remote | +| Python/Bash Functions | Simple testing or non-Ansible use cases | Localhost | + +--- + +## Requirements, Dependencies and Testing + ### Operating System requirements Designed for Linux operating systems, e.g. RHEL. diff --git a/docs/EXEC_EXAMPLES.md b/docs/EXEC_EXAMPLES.md index 21e8cb9..505860c 100644 --- a/docs/EXEC_EXAMPLES.md +++ b/docs/EXEC_EXAMPLES.md @@ -54,7 +54,7 @@ ```shell # Install from local source directory for Ansible 2.11+ -ansible-galaxy collection install ./community.sap_launchpad +ansible-galaxy collection install community.sap_launchpad # Workaround install from local source directory for Ansible 2.9.x # mv ./community.sap_launchpad ~/.ansible/collections/ansible_collections/community @@ -108,14 +108,14 @@ ansible-playbook --timeout 60 ./community.sap_launchpad/playbooks/sample-downloa # Option 2: Use sequential parse/execution, by using include_role inside Task block tasks: - - name: Execute Ansible Role to download SAP software - include_role: - name: { role: community.sap_launchpad.software_center_download } - vars: - suser_id: "{{ suser_id }}" - suser_password: "{{ suser_password }}" - softwarecenter_search_query: "{{ item }}" - with_items: "{{ softwarecenter_search_list }}" + - name: Execute Ansible Role to download SAP software + include_role: + name: { role: community.sap_launchpad.software_center_download } + vars: + suser_id: "{{ suser_id }}" + suser_password: "{{ suser_password }}" + softwarecenter_search_query: "{{ item }}" + loop: "{{ softwarecenter_search_list }}" # Option 3: Use task block with import_roles tasks: @@ -126,7 +126,7 @@ ansible-playbook --timeout 60 ./community.sap_launchpad/playbooks/sample-downloa suser_id: "{{ suser_id }}" suser_password: "{{ suser_password }}" softwarecenter_search_query: "{{ item }}" - with_items: "{{ softwarecenter_search_list }}" + loop: "{{ softwarecenter_search_list }}" ``` From 216f29d46475741761d9e919be0449d9be11b5b4 Mon Sep 17 00:00:00 2001 From: sean-freeman <1815807+sean-freeman@users.noreply.github.com> Date: Thu, 3 Aug 2023 23:34:40 +0100 Subject: [PATCH 2/6] feat: file exist search improvement --- plugins/modules/software_center_download.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/plugins/modules/software_center_download.py b/plugins/modules/software_center_download.py index 4d5ec1b..1dd6b4e 100644 --- a/plugins/modules/software_center_download.py +++ b/plugins/modules/software_center_download.py @@ -83,6 +83,7 @@ ######################### import requests +import glob from ansible.module_utils.basic import AnsibleModule # Import runner @@ -132,10 +133,15 @@ def run_module(): # Main run try: + + # Search directory and subdirectories for filename without file extension filename = query if query else download_filename - if os.path.exists(os.path.join(dest, filename)): - module.exit_json(skipped=True, msg="file {} already exists".format(filename)) + pattern = dest + '/**/' + os.path.splitext(filename)[0] + '.*' + for file in glob.glob(pattern, recursive=True): + if os.path.exists(file): + module.exit_json(skipped=True, msg="file {} already exists".format(filename)) + # Initiate login with given credentials sap_sso_login(username, password) # EXEC: query From 3717ee2684019ad90ae8c54cc06f60ca559a97d9 Mon Sep 17 00:00:00 2001 From: sean-freeman <1815807+sean-freeman@users.noreply.github.com> Date: Thu, 3 Aug 2023 23:38:02 +0100 Subject: [PATCH 3/6] docs: fix url ref --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 721be07..b3fa15c 100644 --- a/README.md +++ b/README.md @@ -45,7 +45,7 @@ When an SAP User ID (e.g. S-User) is enabled with and part of an SAP Universal I In addition, if a SAP Universal ID is used then the recommendation is to check and reset the SAP User ID ‘Account Password’ in the [SAP Universal ID Account Manager](https://account.sap.com/manage/accounts), which will help to avoid any potential conflicts. -For further information regarding connection errors, please see the FAQ section [Errors with prefix 'SAP SSO authentication failed - '](#errors-with-prefix-sap-sso-authentication-failed---). +For further information regarding connection errors, please see the FAQ section [Errors with prefix 'SAP SSO authentication failed - '](./docs/FAQ.md#errors-with-prefix-sap-sso-authentication-failed---). ### Execution examples From c350adfc00fb2748b09c1e4be954fd6c10a3081a Mon Sep 17 00:00:00 2001 From: sean-freeman <1815807+sean-freeman@users.noreply.github.com> Date: Thu, 3 Aug 2023 23:40:42 +0100 Subject: [PATCH 4/6] docs: url ref text --- docs/FAQ.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/FAQ.md b/docs/FAQ.md index fdc695a..ca093b9 100644 --- a/docs/FAQ.md +++ b/docs/FAQ.md @@ -22,7 +22,7 @@ The error HTTP 401 refers to either: - Unauthorized, the SAP User ID is part of an SAP Universal ID and must use the password of the SAP Universal ID - In addition, if a SAP Universal ID is used then the recommendation is to check and reset the SAP User ID ‘Account Password’ in the [SAP Universal ID Account Manager](https://account.sap.com/manage/accounts), which will help to avoid any potential conflicts. -This is documented under [Ansible Collection for SAP Launchpad - Requirements, Dependencies and Testing](https://github.com/sap-linuxlab/community.sap_launchpad#requirements-dependencies-and-testing) +This is documented under [Execution - Credentials](https://github.com/sap-linuxlab/community.sap_launchpad#requirements-dependencies-and-testing). ### 'SAP SSO authentication failed - 404 Client Error: Not Found for url: `https://origin.softwaredownloads.sap.com/tokengen/?file=___`' From a6d911590ef925ec75edd1ddfd1bba2483daf136 Mon Sep 17 00:00:00 2001 From: sean-freeman <1815807+sean-freeman@users.noreply.github.com> Date: Fri, 4 Aug 2023 18:25:39 +0100 Subject: [PATCH 5/6] fix: file exist search when no file ext --- plugins/modules/software_center_download.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/modules/software_center_download.py b/plugins/modules/software_center_download.py index 1dd6b4e..0cc8ca9 100644 --- a/plugins/modules/software_center_download.py +++ b/plugins/modules/software_center_download.py @@ -136,10 +136,10 @@ def run_module(): # Search directory and subdirectories for filename without file extension filename = query if query else download_filename - pattern = dest + '/**/' + os.path.splitext(filename)[0] + '.*' + pattern = dest + '/**/' + os.path.splitext(filename)[0] + '*' for file in glob.glob(pattern, recursive=True): if os.path.exists(file): - module.exit_json(skipped=True, msg="file {} already exists".format(filename)) + module.exit_json(skipped=True, msg="file {} already exists".format(file)) # Initiate login with given credentials sap_sso_login(username, password) From 0120ad5d31cbbe29b5eefb46a6fe30b84ea8e1e6 Mon Sep 17 00:00:00 2001 From: sean-freeman <1815807+sean-freeman@users.noreply.github.com> Date: Fri, 4 Aug 2023 18:30:22 +0100 Subject: [PATCH 6/6] docs: sample updates --- docs/EXEC_EXAMPLES.md | 34 ++++++++++++++----- playbooks/sample-download-install-media.yml | 19 +++++++---- ...ple-maintenance-planner-files-download.yml | 33 ++++++++++-------- 3 files changed, 56 insertions(+), 30 deletions(-) diff --git a/docs/EXEC_EXAMPLES.md b/docs/EXEC_EXAMPLES.md index 505860c..de5282f 100644 --- a/docs/EXEC_EXAMPLES.md +++ b/docs/EXEC_EXAMPLES.md @@ -41,13 +41,18 @@ # Use task block to call Ansible Module tasks: - - 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: "{{ item }}" - dest: "/tmp/" - with_items: "{{ softwarecenter_search_list }}" + - 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: "{{ item }}" + dest: "/tmp/" + loop: "{{ softwarecenter_search_list }}" + loop_control: + label: "{{ item }} : {{ download_task.msg }}" + register: download_task + retries: 1 + until: download_task is not failed ``` **Execution of Ansible Playbook, with in-line Ansible Inventory set as localhost** @@ -115,7 +120,13 @@ ansible-playbook --timeout 60 ./community.sap_launchpad/playbooks/sample-downloa suser_id: "{{ suser_id }}" suser_password: "{{ suser_password }}" softwarecenter_search_query: "{{ item }}" - loop: "{{ softwarecenter_search_list }}" + loop: "{{ softwarecenter_search_list }}" + loop_control: + label: "{{ item }} : {{ download_task.msg }}" + register: download_task + retries: 1 + until: download_task is not failed + # Option 3: Use task block with import_roles tasks: @@ -126,7 +137,12 @@ ansible-playbook --timeout 60 ./community.sap_launchpad/playbooks/sample-downloa suser_id: "{{ suser_id }}" suser_password: "{{ suser_password }}" softwarecenter_search_query: "{{ item }}" - loop: "{{ softwarecenter_search_list }}" + loop: "{{ softwarecenter_search_list }}" + loop_control: + label: "{{ item }} : {{ download_task.msg }}" + register: download_task + retries: 1 + until: download_task is not failed ``` diff --git a/playbooks/sample-download-install-media.yml b/playbooks/sample-download-install-media.yml index d8977d8..a4f4b18 100644 --- a/playbooks/sample-download-install-media.yml +++ b/playbooks/sample-download-install-media.yml @@ -35,10 +35,15 @@ # Use task block to call Ansible Module tasks: - - 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: "{{ item }}" - dest: "/tmp/" - with_items: "{{ softwarecenter_search_list }}" + - 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: "{{ item }}" + dest: "/tmp/" + loop: "{{ softwarecenter_search_list }}" + loop_control: + label: "{{ item }} : {{ download_task.msg }}" + register: download_task + retries: 1 + until: download_task is not failed diff --git a/playbooks/sample-maintenance-planner-files-download.yml b/playbooks/sample-maintenance-planner-files-download.yml index fbf7f88..8bc0ea1 100644 --- a/playbooks/sample-maintenance-planner-files-download.yml +++ b/playbooks/sample-maintenance-planner-files-download.yml @@ -24,22 +24,27 @@ # Use task block to call Ansible Module tasks: - - name: Execute Ansible Module 'maintenance_planner_files' to get files from MP - community.sap_launchpad.maintenance_planner_files: - suser_id: "{{ suser_id }}" - suser_password: "{{ suser_password }}" - transaction_name: "{{ mp_transaction_name }}" - register: sap_maintenance_planner_basket_register + - name: Execute Ansible Module 'maintenance_planner_files' to get files from MP + community.sap_launchpad.maintenance_planner_files: + suser_id: "{{ suser_id }}" + suser_password: "{{ suser_password }}" + transaction_name: "{{ mp_transaction_name }}" + register: sap_maintenance_planner_basket_register # - debug: # msg: # - "{{ sap_maintenance_planner_basket_register.download_basket }}" - - name: Execute Ansible Module 'software_center_download' to download files - community.sap_launchpad.software_center_download: - suser_id: "{{ suser_id }}" - suser_password: "{{ suser_password }}" - download_link: "{{ item.DirectLink }}" - download_filename: "{{ item.Filename }}" - dest: "/tmp/test" - loop: "{{ sap_maintenance_planner_basket_register.download_basket }}" + - name: Execute Ansible Module 'software_center_download' to download files + community.sap_launchpad.software_center_download: + suser_id: "{{ suser_id }}" + suser_password: "{{ suser_password }}" + download_link: "{{ item.DirectLink }}" + download_filename: "{{ item.Filename }}" + dest: "/tmp/test" + loop: "{{ sap_maintenance_planner_basket_register.download_basket }}" + loop_control: + label: "{{ item }} : {{ download_task.msg }}" + register: download_task + retries: 1 + until: download_task is not failed