summaryrefslogtreecommitdiffstats
path: root/ansible_collections/community/sap
diff options
context:
space:
mode:
Diffstat (limited to 'ansible_collections/community/sap')
-rw-r--r--ansible_collections/community/sap/.github/workflows/ansible-test.yml230
-rw-r--r--ansible_collections/community/sap/CHANGELOG.rst42
-rw-r--r--ansible_collections/community/sap/FILES.json142
-rw-r--r--ansible_collections/community/sap/MANIFEST.json10
-rw-r--r--ansible_collections/community/sap/README.md8
-rw-r--r--ansible_collections/community/sap/changelogs/changelog.yaml23
-rw-r--r--ansible_collections/community/sap/changelogs/config.yaml1
-rw-r--r--ansible_collections/community/sap/meta/runtime.yml31
-rw-r--r--ansible_collections/community/sap/plugins/modules/__init__.py0
-rw-r--r--ansible_collections/community/sap/plugins/modules/database/saphana/hana_query.py238
-rw-r--r--ansible_collections/community/sap/plugins/modules/files/sapcar_extract.py220
-rw-r--r--ansible_collections/community/sap/plugins/modules/hana_query.py238
-rw-r--r--ansible_collections/community/sap/plugins/modules/identity/sap_company.py326
-rw-r--r--ansible_collections/community/sap/plugins/modules/identity/sap_user.py499
-rw-r--r--ansible_collections/community/sap/plugins/modules/sap_company.py326
-rw-r--r--ansible_collections/community/sap/plugins/modules/sap_snote.py258
-rw-r--r--ansible_collections/community/sap/plugins/modules/sap_system_facts.py206
-rw-r--r--ansible_collections/community/sap/plugins/modules/sap_task_list_execute.py340
-rw-r--r--ansible_collections/community/sap/plugins/modules/sap_user.py499
-rw-r--r--ansible_collections/community/sap/plugins/modules/sapcar_extract.py220
-rw-r--r--ansible_collections/community/sap/plugins/modules/system/sap_snote.py258
-rw-r--r--ansible_collections/community/sap/plugins/modules/system/sap_system_facts.py206
-rw-r--r--ansible_collections/community/sap/plugins/modules/system/sap_task_list_execute.py340
23 files changed, 221 insertions, 4440 deletions
diff --git a/ansible_collections/community/sap/.github/workflows/ansible-test.yml b/ansible_collections/community/sap/.github/workflows/ansible-test.yml
index 1671f6579..c29b8123a 100644
--- a/ansible_collections/community/sap/.github/workflows/ansible-test.yml
+++ b/ansible_collections/community/sap/.github/workflows/ansible-test.yml
@@ -1,126 +1,126 @@
-name: CI
-on:
- # Run CI against all pushes (direct commits, also merged PRs), Pull Requests
- push:
- pull_request:
- # Run CI once per day (at 06:00 UTC)
- # This ensures that even if there haven't been commits that we are still testing against latest version of ansible-test for each ansible-base version
- schedule:
- - cron: '0 6 * * *'
-env:
- NAMESPACE: community
- COLLECTION_NAME: sap
+# name: CI
+# on:
+# # Run CI against all pushes (direct commits, also merged PRs), Pull Requests
+# push:
+# pull_request:
+# # Run CI once per day (at 06:00 UTC)
+# # This ensures that even if there haven't been commits that we are still testing against latest version of ansible-test for each ansible-base version
+# schedule:
+# - cron: '0 6 * * *'
+# env:
+# NAMESPACE: community
+# COLLECTION_NAME: sap
-jobs:
- sanity:
- name: Sanity (Ⓐ${{ matrix.ansible }})
- strategy:
- matrix:
- ansible:
- - stable-2.9
- - stable-2.10
- - stable-2.11
- - stable-2.12
- - devel
- runs-on: ubuntu-latest
- steps:
+# jobs:
+# sanity:
+# name: Sanity (Ⓐ${{ matrix.ansible }})
+# strategy:
+# matrix:
+# ansible:
+# - stable-2.9
+# - stable-2.10
+# - stable-2.11
+# - stable-2.12
+# - devel
+# runs-on: ubuntu-latest
+# steps:
- - name: Check out code
- uses: actions/checkout@v2
+# - name: Check out code
+# uses: actions/checkout@v2
- - name: Perform sanity testing with ansible-test
- uses: ansible-community/ansible-test-gh-action@release/v1
- with:
- ansible-core-version: ${{ matrix.ansible }}
- testing-type: sanity
+# - name: Perform sanity testing with ansible-test
+# uses: ansible-community/ansible-test-gh-action@release/v1
+# with:
+# ansible-core-version: ${{ matrix.ansible }}
+# testing-type: sanity
- units:
- runs-on: ubuntu-latest
- name: Units (Ⓐ${{ matrix.ansible }}+py${{ matrix.python }})
- strategy:
- # As soon as the first unit test fails, cancel the others to free up the CI queue
- fail-fast: true
- matrix:
- ansible:
- - stable-2.9 # Only if your collection supports Ansible 2.9
- - stable-2.10
- - stable-2.11
- - stable-2.12
- - devel
- python:
- - 2.6
- - 2.7
- - 3.5
- - 3.6
- - 3.7
- - 3.8
- - 3.9
- exclude:
- # Because ansible-test doesn't support python3.9 for Ansible 2.9
- - ansible: stable-2.9
- python: 3.9
- - ansible: devel
- python: 2.6
+# units:
+# runs-on: ubuntu-latest
+# name: Units (Ⓐ${{ matrix.ansible }}+py${{ matrix.python }})
+# strategy:
+# # As soon as the first unit test fails, cancel the others to free up the CI queue
+# fail-fast: true
+# matrix:
+# ansible:
+# - stable-2.9 # Only if your collection supports Ansible 2.9
+# - stable-2.10
+# - stable-2.11
+# - stable-2.12
+# - devel
+# python:
+# - 2.6
+# - 2.7
+# - 3.5
+# - 3.6
+# - 3.7
+# - 3.8
+# - 3.9
+# exclude:
+# # Because ansible-test doesn't support python3.9 for Ansible 2.9
+# - ansible: stable-2.9
+# python: 3.9
+# - ansible: devel
+# python: 2.6
- steps:
- - name: Check out code
- uses: actions/checkout@v2
+# steps:
+# - name: Check out code
+# uses: actions/checkout@v2
- - name: Perform unit testing with ansible-test
- uses: ansible-community/ansible-test-gh-action@release/v1
- with:
- ansible-core-version: ${{ matrix.ansible }}
- target-python-version: ${{ matrix.python }}
- python-version: 3.8
- testing-type: units
- test-deps: >-
- ansible.netcommon
- ansible.utils
+# - name: Perform unit testing with ansible-test
+# uses: ansible-community/ansible-test-gh-action@release/v1
+# with:
+# ansible-core-version: ${{ matrix.ansible }}
+# target-python-version: ${{ matrix.python }}
+# python-version: 3.8
+# testing-type: units
+# test-deps: >-
+# ansible.netcommon
+# ansible.utils
-# Please consult the Readme for information on why we disabled integration tests temporarily.
+# # Please consult the Readme for information on why we disabled integration tests temporarily.
- # integration:
- # runs-on: ubuntu-latest
- # name: I (Ⓐ${{ matrix.ansible }}+py${{ matrix.python }})
- # strategy:
- # fail-fast: false
- # matrix:
- # ansible:
- # - stable-2.9 # Only if your collection supports Ansible 2.9
- # - stable-2.10
- # - stable-2.11
- # - stable-2.12
- # - devel
- # python:
- # - 2.6
- # - 2.7
- # - 3.5
- # - 3.6
- # - 3.7
- # - 3.8
- # - 3.9
- # exclude:
- # # Because ansible-test doesn't support python3.9 for Ansible 2.9
- # - ansible: stable-2.9
- # python: 3.9
- # - ansible: devel
- # python: 2.6
+# # integration:
+# # runs-on: ubuntu-latest
+# # name: I (Ⓐ${{ matrix.ansible }}+py${{ matrix.python }})
+# # strategy:
+# # fail-fast: false
+# # matrix:
+# # ansible:
+# # - stable-2.9 # Only if your collection supports Ansible 2.9
+# # - stable-2.10
+# # - stable-2.11
+# # - stable-2.12
+# # - devel
+# # python:
+# # - 2.6
+# # - 2.7
+# # - 3.5
+# # - 3.6
+# # - 3.7
+# # - 3.8
+# # - 3.9
+# # exclude:
+# # # Because ansible-test doesn't support python3.9 for Ansible 2.9
+# # - ansible: stable-2.9
+# # python: 3.9
+# # - ansible: devel
+# # python: 2.6
- # steps:
- # - name: Check out code
- # uses: actions/checkout@v2
+# # steps:
+# # - name: Check out code
+# # uses: actions/checkout@v2
- # - name: Perform integration testing with ansible-test
- # uses: ansible-community/ansible-test-gh-action@release/v1
- # with:
- # ansible-core-version: ${{ matrix.ansible }}
- # python-version: 3.8
- # pre-test-cmd: >-
- # mkdir -p tests/output/
- # touch tests/output/coverage
- # target-python-version: ${{ matrix.python }}
- # testing-type: integration
- # test-deps: >-
- # ansible.netcommon
- # ansible.utils
+# # - name: Perform integration testing with ansible-test
+# # uses: ansible-community/ansible-test-gh-action@release/v1
+# # with:
+# # ansible-core-version: ${{ matrix.ansible }}
+# # python-version: 3.8
+# # pre-test-cmd: >-
+# # mkdir -p tests/output/
+# # touch tests/output/coverage
+# # target-python-version: ${{ matrix.python }}
+# # testing-type: integration
+# # test-deps: >-
+# # ansible.netcommon
+# # ansible.utils
diff --git a/ansible_collections/community/sap/CHANGELOG.rst b/ansible_collections/community/sap/CHANGELOG.rst
index 2662ad232..714ed15a5 100644
--- a/ansible_collections/community/sap/CHANGELOG.rst
+++ b/ansible_collections/community/sap/CHANGELOG.rst
@@ -5,15 +5,37 @@ Community SAP Release Notes
.. contents:: Topics
+v2.0.0
+======
+
+Release Summary
+---------------
+
+This release deprecates all modules and redirect them to community.sap_libs. The modules are removed in this release.
+The modules are available in the community.sap_libs repository.
+
+Major Changes
+-------------
+
+- all modules - everything is now a redirect to the new collection community.sap_libs
+
+Deprecated Features
+-------------------
+
+- community.sap.hana_query - is deprecated in favor of community.sap_libs.sap_hdbsql
+- community.sap.sap_company - is deprecated in favor of community.sap_libs.sap_company
+- community.sap.sap_snote - is deprecated in favor of community.sap_libs.sap_snote
+- community.sap.sap_task_list_execute - is deprecated in favor of community.sap_libs.sap_task_list_execute
+- community.sap.sap_user - is deprecated in favor of community.sap_libs.sap_user
+- community.sap.sapcar_extract - is deprecated in favor of community.sap_libs.sapcar_extract
+
v1.0.0
======
Release Summary
---------------
-This is the fir major release of the ``community.sap`` collection.
-This changelog contains all changes to the modules and plugins in this collection
-that have been made after the previous release.
+This is the first major release of the ``community.sap`` collection. This changelog contains all changes to the modules and plugins in this collection that have been made after the previous release.
Minor Changes
-------------
@@ -26,14 +48,14 @@ New Modules
Identity
~~~~~~~~
-- identity.sap_company - This module will manage a company entities in a SAP S4HANA environment
-- identity.sap_user - This module will manage a user entities in a SAP S4/HANA environment
+- sap_company - This module will manage a company entities in a SAP S4HANA environment
+- sap_user - This module will manage a user entities in a SAP S4/HANA environment
System
~~~~~~
-- system.sap_snote - This module will upload and (de)implements C(SNOTES) in a SAP S4HANA environment.
-- system.sap_system_facts - Gathers SAP facts in a host
+- sap_snote - This module will upload and (de)implements C(SNOTES) in a SAP S4HANA environment.
+- sap_system_facts - Gathers SAP facts in a host
v0.1.0
======
@@ -52,14 +74,14 @@ Database
saphana
^^^^^^^
-- database.saphana.hana_query - Execute SQL on HANA
+- hana_query - Execute SQL on HANA
Files
~~~~~
-- files.sapcar_extract - Manages SAP SAPCAR archives
+- sapcar_extract - Manages SAP SAPCAR archives
System
~~~~~~
-- system.sap_task_list_execute - Perform SAP Task list execution
+- sap_task_list_execute - Perform SAP Task list execution
diff --git a/ansible_collections/community/sap/FILES.json b/ansible_collections/community/sap/FILES.json
index 94f9d13cb..05e702336 100644
--- a/ansible_collections/community/sap/FILES.json
+++ b/ansible_collections/community/sap/FILES.json
@@ -60,7 +60,7 @@
"name": ".github/workflows/ansible-test.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "b33230275f011323f420a5c0bac294a83590804750a1895e78ab9d8f0e89e874",
+ "chksum_sha256": "141fb2c403baf2847bf06f9281f397e22fc5325262ef017cace4bde09d6f803d",
"format": 1
},
{
@@ -102,14 +102,14 @@
"name": "changelogs/changelog.yaml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "6638411429b43df9657c1fda5c88510094303f9f58b929c5676f66fac72b8d4c",
+ "chksum_sha256": "d58ffee3cafd91ae2cebaa92a66100609fcf1a19501b2e00c1d5b93d0bbc7fcb",
"format": 1
},
{
"name": "changelogs/config.yaml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "60799a00c74a20f69eadcfd8e4fa218bf3d118cc3d6bc2e538ff6efb47760d00",
+ "chksum_sha256": "5f253a9432287fcdfe3100b556bf39d442a5e8b5a5fd3ec4a971f37f954ebac0",
"format": 1
},
{
@@ -123,7 +123,7 @@
"name": "meta/runtime.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "df18179bb2f5447a56ac92261a911649b96821c0b2c08eea62d5cc6b0195203f",
+ "chksum_sha256": "9a8c86337928225fea4abd7361f2813f48b1770c4ae83aac940e7b491a4e143a",
"format": 1
},
{
@@ -169,136 +169,10 @@
"format": 1
},
{
- "name": "plugins/modules/hana_query.py",
+ "name": "plugins/modules/__init__.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "44ffd7642f1285a808a04bb7772a1869c4a0075a049c6370f98c53c5581ad8b6",
- "format": 1
- },
- {
- "name": "plugins/modules/sap_company.py",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "daf9bd3a40aba75148729b1b10fd4c4d0a320d6660228bce8d7c1cd90c6bf5e8",
- "format": 1
- },
- {
- "name": "plugins/modules/sap_snote.py",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "52b12cacc618430f176efc1cd91021bf83e74ed9f4d2febf7f1200241fb559bb",
- "format": 1
- },
- {
- "name": "plugins/modules/sap_system_facts.py",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "def5406922e38fb12999ebd2463bf3e560dd2cc7b6052c63426b4277e2963b23",
- "format": 1
- },
- {
- "name": "plugins/modules/sap_task_list_execute.py",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "62052a6017278b4bc1d22bad9f0638f4fc78f5b2ba7de72870fa5de5cf15c96c",
- "format": 1
- },
- {
- "name": "plugins/modules/sap_user.py",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "73079c029034e5d047231f06b0302d362c23b494448a856011bad7a2d93abd62",
- "format": 1
- },
- {
- "name": "plugins/modules/sapcar_extract.py",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "52a51f17cd9f0ffd5ddeb63d2c397526db7ced2c78fc3008385e9ca00659ae72",
- "format": 1
- },
- {
- "name": "plugins/modules/database",
- "ftype": "dir",
- "chksum_type": null,
- "chksum_sha256": null,
- "format": 1
- },
- {
- "name": "plugins/modules/database/saphana",
- "ftype": "dir",
- "chksum_type": null,
- "chksum_sha256": null,
- "format": 1
- },
- {
- "name": "plugins/modules/database/saphana/hana_query.py",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "44ffd7642f1285a808a04bb7772a1869c4a0075a049c6370f98c53c5581ad8b6",
- "format": 1
- },
- {
- "name": "plugins/modules/files",
- "ftype": "dir",
- "chksum_type": null,
- "chksum_sha256": null,
- "format": 1
- },
- {
- "name": "plugins/modules/files/sapcar_extract.py",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "52a51f17cd9f0ffd5ddeb63d2c397526db7ced2c78fc3008385e9ca00659ae72",
- "format": 1
- },
- {
- "name": "plugins/modules/identity",
- "ftype": "dir",
- "chksum_type": null,
- "chksum_sha256": null,
- "format": 1
- },
- {
- "name": "plugins/modules/identity/sap_company.py",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "daf9bd3a40aba75148729b1b10fd4c4d0a320d6660228bce8d7c1cd90c6bf5e8",
- "format": 1
- },
- {
- "name": "plugins/modules/identity/sap_user.py",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "73079c029034e5d047231f06b0302d362c23b494448a856011bad7a2d93abd62",
- "format": 1
- },
- {
- "name": "plugins/modules/system",
- "ftype": "dir",
- "chksum_type": null,
- "chksum_sha256": null,
- "format": 1
- },
- {
- "name": "plugins/modules/system/sap_snote.py",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "52b12cacc618430f176efc1cd91021bf83e74ed9f4d2febf7f1200241fb559bb",
- "format": 1
- },
- {
- "name": "plugins/modules/system/sap_system_facts.py",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "def5406922e38fb12999ebd2463bf3e560dd2cc7b6052c63426b4277e2963b23",
- "format": 1
- },
- {
- "name": "plugins/modules/system/sap_task_list_execute.py",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "62052a6017278b4bc1d22bad9f0638f4fc78f5b2ba7de72870fa5de5cf15c96c",
+ "chksum_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"format": 1
},
{
@@ -606,7 +480,7 @@
"name": "CHANGELOG.rst",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "96de6ff24a33521295f40c708f78bd801ce7a7cf5756a2982e292fc8de826d5e",
+ "chksum_sha256": "63e3ec595a36659d4977981c1abfd3c8efb0fe2eace862746feabe968e13ba3f",
"format": 1
},
{
@@ -648,7 +522,7 @@
"name": "README.md",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "241e90547fb638d794abf998542e9e72675b4ce97ed1e3ff223267f195818a63",
+ "chksum_sha256": "d600b5ca720d33e93ee89c9bdfba410c8f7dc435fa29ea7ca4ebfa3159f4311b",
"format": 1
},
{
diff --git a/ansible_collections/community/sap/MANIFEST.json b/ansible_collections/community/sap/MANIFEST.json
index b03f312a2..5385f2f71 100644
--- a/ansible_collections/community/sap/MANIFEST.json
+++ b/ansible_collections/community/sap/MANIFEST.json
@@ -2,7 +2,7 @@
"collection_info": {
"namespace": "community",
"name": "sap",
- "version": "1.0.0",
+ "version": "2.0.0",
"authors": [
"Rainer Leber (github.com/rainerleber)",
"Robert Kraemer (github.com/rkpobe)"
@@ -14,9 +14,11 @@
"description": "SAP community collection for Ansible",
"license": [],
"license_file": "LICENSE",
- "dependencies": {},
+ "dependencies": {
+ "community.sap_libs": ">=1.0.0"
+ },
"repository": "https://github.com/ansible-collections/community.sap",
- "documentation": "https://github.com/ansible-collection/community.sap/tree/main/docs",
+ "documentation": "https://github.com/ansible-collection/community.sap",
"homepage": "https://github.com/ansible-collections/community.sap",
"issues": "https://github.com/ansible-collections/community.sap/issues"
},
@@ -24,7 +26,7 @@
"name": "FILES.json",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "37274fcb06645cec88067238f9d976cb36d1a807453950618d6f8537de8483bc",
+ "chksum_sha256": "90eb59f365d6576a46b04852a21d5998d4ad14dcbb20ae1547d5a1667dcda9d9",
"format": 1
},
"format": 1
diff --git a/ansible_collections/community/sap/README.md b/ansible_collections/community/sap/README.md
index 84940afce..dd935b270 100644
--- a/ansible_collections/community/sap/README.md
+++ b/ansible_collections/community/sap/README.md
@@ -1,5 +1,11 @@
-# Community SAP Collection
+# Deprecated Community SAP Collection
+# **WARNING: This collection is deprecated, not maintained anymore and superseded by the collection [**community.sap_libs**](https://github.com/sap-linuxlab/community.sap_libs)**
+
+**Feel free to raise issues at the new place.
+All CI tests are disabled.**
+
+---
This repository contains the community.sap Ansible Collection. The collection includes modules and plugins supported by the Ansible SAP community to help SAP landscape management.
# SAP Collection for Ansible
diff --git a/ansible_collections/community/sap/changelogs/changelog.yaml b/ansible_collections/community/sap/changelogs/changelog.yaml
index bfa4aa056..39f79a298 100644
--- a/ansible_collections/community/sap/changelogs/changelog.yaml
+++ b/ansible_collections/community/sap/changelogs/changelog.yaml
@@ -21,9 +21,9 @@ releases:
changes:
minor_changes:
- sapcar_extract.py - more strict logic for filenames
- release_summary: 'This is the first major release of the ``community.sap`` collection.
+ release_summary: This is the first major release of the ``community.sap`` collection.
This changelog contains all changes to the modules and plugins in this collection
- that have been made after the previous release.'
+ that have been made after the previous release.
fragments:
- 1.0.0.yml
- 11-filenamesuffixcheck.yml
@@ -42,3 +42,22 @@ releases:
name: sap_user
namespace: identity
release_date: '2022-02-17'
+ 2.0.0:
+ changes:
+ deprecated_features:
+ - community.sap.hana_query - is deprecated in favor of community.sap_libs.sap_hdbsql
+ - community.sap.sap_company - is deprecated in favor of community.sap_libs.sap_company
+ - community.sap.sap_snote - is deprecated in favor of community.sap_libs.sap_snote
+ - community.sap.sap_task_list_execute - is deprecated in favor of community.sap_libs.sap_task_list_execute
+ - community.sap.sap_user - is deprecated in favor of community.sap_libs.sap_user
+ - community.sap.sapcar_extract - is deprecated in favor of community.sap_libs.sapcar_extract
+ major_changes:
+ - all modules - everything is now a redirect to the new collection community.sap_libs
+ release_summary: 'This release deprecates all modules and redirect them to community.sap_libs.
+ The modules are removed in this release.
+
+ The modules are available in the community.sap_libs repository.'
+ fragments:
+ - 0029-deprecation.yml
+ - 2.0.0.yml
+ release_date: '2023-07-14'
diff --git a/ansible_collections/community/sap/changelogs/config.yaml b/ansible_collections/community/sap/changelogs/config.yaml
index 76c44c97e..db443763c 100644
--- a/ansible_collections/community/sap/changelogs/config.yaml
+++ b/ansible_collections/community/sap/changelogs/config.yaml
@@ -4,6 +4,7 @@ changes_file: changelog.yaml
changes_format: combined
keep_fragments: false
mention_ancestor: true
+flatmap: true
new_plugins_after_name: removed_features
notesdir: fragments
prelude_section_name: release_summary
diff --git a/ansible_collections/community/sap/meta/runtime.yml b/ansible_collections/community/sap/meta/runtime.yml
index 2ee3c9fa9..15cbcba59 100644
--- a/ansible_collections/community/sap/meta/runtime.yml
+++ b/ansible_collections/community/sap/meta/runtime.yml
@@ -1,2 +1,33 @@
---
requires_ansible: '>=2.9.10'
+
+plugin_routing:
+ modules:
+ community.sap.hana_query:
+ redirect: community.sap_libs.sap_hdbsql
+ deprecation:
+ warning_text: Use community.sap_libs.sap_hdbsql instead.
+ community.sap.sap_company:
+ redirect: community.sap_libs.sap_company
+ deprecation:
+ warning_text: Use community.sap_libs.sap_company instead.
+ community.sap.sap_snote:
+ redirect: community.sap_libs.sap_snote
+ deprecation:
+ warning_text: Use community.sap_libs.sap_snote instead.
+ community.sap.sap_snote:
+ redirect: community.sap_libs.sap_system_facts
+ deprecation:
+ warning_text: Use community.sap_libs.sap_system_facts instead.
+ community.sap.sap_user:
+ redirect: community.sap_libs.sap_user
+ deprecation:
+ warning_text: Use community.sap_libs.sap_user instead.
+ community.sap.sap_task_list_execute:
+ redirect: community.sap_libs.sap_task_list_execute
+ deprecation:
+ warning_text: Use community.sap_libs.sap_task_list_execute instead.
+ community.sap.sapcar_extract:
+ redirect: community.sap_libs.sapcar_extract
+ deprecation:
+ warning_text: Use community.sap_libs.sapcar_extract instead.
diff --git a/ansible_collections/community/sap/plugins/modules/__init__.py b/ansible_collections/community/sap/plugins/modules/__init__.py
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/ansible_collections/community/sap/plugins/modules/__init__.py
diff --git a/ansible_collections/community/sap/plugins/modules/database/saphana/hana_query.py b/ansible_collections/community/sap/plugins/modules/database/saphana/hana_query.py
deleted file mode 100644
index 9eb43db09..000000000
--- a/ansible_collections/community/sap/plugins/modules/database/saphana/hana_query.py
+++ /dev/null
@@ -1,238 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-
-# Copyright: (c) 2021, Rainer Leber <rainerleber@gmail.com>
-# 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: hana_query
-short_description: Execute SQL on HANA
-version_added: "0.1.0"
-description: This module executes SQL statements on HANA with hdbsql.
-options:
- sid:
- description: The system ID.
- type: str
- required: false
- bin_path:
- description: The path to the hdbsql binary.
- type: str
- required: false
- instance:
- description: The instance number.
- type: str
- required: true
- user:
- description: A dedicated username. The user could be also in hdbuserstore.
- type: str
- default: SYSTEM
- userstore:
- description: If C(true), the user must be in hdbuserstore.
- type: bool
- default: false
- password:
- description:
- - The password to connect to the database.
- - "B(Note:) Since the passwords have to be passed as command line arguments, I(userstore=true) should
- be used whenever possible, as command line arguments can be seen by other users
- on the same machine."
- type: str
- autocommit:
- description: Autocommit the statement.
- type: bool
- default: true
- host:
- description: The Host IP address. The port can be defined as well.
- type: str
- database:
- description: Define the database on which to connect.
- type: str
- encrypted:
- description: Use encrypted connection.
- type: bool
- default: false
- filepath:
- description:
- - One or more files each containing one SQL query to run.
- - Must be a string or list containing strings.
- type: list
- elements: path
- query:
- description:
- - SQL query to run.
- - Must be a string or list containing strings. Please note that if you supply a string, it will be split by commas (C(,)) to a list.
- It is better to supply a one-element list instead to avoid mangled input.
- type: list
- elements: str
-notes:
- - Does not support C(check_mode). Always reports that the state has changed even if no changes have been made.
-author:
- - Rainer Leber (@rainerleber)
-'''
-
-EXAMPLES = r'''
-- name: Simple select query
- community.sap.hana_query:
- sid: "hdb"
- instance: "01"
- password: "Test123"
- query: select user_name from users
-
-- name: RUN select query with host port
- community.sap.hana_query:
- sid: "hdb"
- instance: "01"
- password: "Test123"
- host: "10.10.2.4:30001"
- query: select user_name from users
-
-- name: Run several queries
- community.sap.hana_query:
- sid: "hdb"
- instance: "01"
- password: "Test123"
- query:
- - select user_name from users
- - select * from SYSTEM
- host: "localhost"
- autocommit: False
-
-- name: Run several queries with path
- community.sap.hana_query:
- bin_path: "/usr/sap/HDB/HDB01/exe/hdbsql"
- instance: "01"
- password: "Test123"
- query:
- - select user_name from users
- - select * from users
- host: "localhost"
- autocommit: False
-
-- name: Run several queries from file
- community.sap.hana_query:
- sid: "hdb"
- instance: "01"
- password: "Test123"
- filepath:
- - /tmp/HANA_CPU_UtilizationPerCore_2.00.020+.txt
- - /tmp/HANA.txt
- host: "localhost"
-
-- name: Run several queries from user store
- community.sap.hana_query:
- sid: "hdb"
- instance: "01"
- user: hdbstoreuser
- userstore: true
- query:
- - select user_name from users
- - select * from users
- autocommit: False
-'''
-
-RETURN = r'''
-query_result:
- description: List containing results of all queries executed (one sublist for every query).
- returned: on success
- type: list
- elements: list
- sample: [[{"Column": "Value1"}, {"Column": "Value2"}], [{"Column": "Value1"}, {"Column": "Value2"}]]
-'''
-
-import csv
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.six import StringIO
-from ansible.module_utils.common.text.converters import to_native
-
-
-def csv_to_list(rawcsv):
- reader_raw = csv.DictReader(StringIO(rawcsv))
- reader = [dict((k, v.strip()) for k, v in row.items()) for row in reader_raw]
- return list(reader)
-
-
-def main():
- module = AnsibleModule(
- argument_spec=dict(
- sid=dict(type='str', required=False),
- bin_path=dict(type='str', required=False),
- instance=dict(type='str', required=True),
- encrypted=dict(type='bool', default=False),
- host=dict(type='str', required=False),
- user=dict(type='str', default="SYSTEM"),
- userstore=dict(type='bool', default=False),
- password=dict(type='str', no_log=True),
- database=dict(type='str', required=False),
- query=dict(type='list', elements='str', required=False),
- filepath=dict(type='list', elements='path', required=False),
- autocommit=dict(type='bool', default=True),
- ),
- required_one_of=[('query', 'filepath'), ('sid', 'instance')],
- required_if=[('userstore', False, ['password'])],
- supports_check_mode=False,
- )
- rc, out, err, out_raw = [0, [], "", ""]
-
- params = module.params
-
- sid = params['sid']
- bin_path = params['bin_path']
- instance = params['instance']
- user = params['user']
- userstore = params['userstore']
- password = params['password']
- autocommit = params['autocommit']
- host = params['host']
- database = params['database']
- encrypted = params['encrypted']
-
- filepath = params['filepath']
- query = params['query']
-
- if bin_path is None:
- bin_path = "/usr/sap/{sid}/HDB{instance}/exe/hdbsql".format(sid=sid.upper(), instance=instance)
-
- try:
- command = [module.get_bin_path(bin_path, required=True)]
- except Exception as e:
- module.fail_json(msg='Failed to find hdbsql at the expected path "{0}".Please check SID and instance number: "{1}"'.format(bin_path, to_native(e)))
-
- if encrypted is True:
- command.extend(['-attemptencrypt'])
- if autocommit is False:
- command.extend(['-z'])
- if host is not None:
- command.extend(['-n', host])
- if database is not None:
- command.extend(['-d', database])
- # -x Suppresses additional output, such as the number of selected rows in a result set.
- if userstore:
- command.extend(['-x', '-U', user])
- else:
- command.extend(['-x', '-i', instance, '-u', user, '-p', password])
-
- if filepath is not None:
- command.extend(['-I'])
- for p in filepath:
- # makes a command like hdbsql -i 01 -u SYSTEM -p secret123# -I /tmp/HANA_CPU_UtilizationPerCore_2.00.020+.txt,
- # iterates through files and append the output to var out.
- query_command = command + [p]
- (rc, out_raw, err) = module.run_command(query_command)
- out.append(csv_to_list(out_raw))
- if query is not None:
- for q in query:
- # makes a command like hdbsql -i 01 -u SYSTEM -p secret123# "select user_name from users",
- # iterates through multiple commands and append the output to var out.
- query_command = command + [q]
- (rc, out_raw, err) = module.run_command(query_command)
- out.append(csv_to_list(out_raw))
- changed = True
-
- module.exit_json(changed=changed, rc=rc, query_result=out, stderr=err)
-
-
-if __name__ == '__main__':
- main()
diff --git a/ansible_collections/community/sap/plugins/modules/files/sapcar_extract.py b/ansible_collections/community/sap/plugins/modules/files/sapcar_extract.py
deleted file mode 100644
index d586dd330..000000000
--- a/ansible_collections/community/sap/plugins/modules/files/sapcar_extract.py
+++ /dev/null
@@ -1,220 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-
-# Copyright: (c) 2021, Rainer Leber <rainerleber@gmail.com>
-# 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: sapcar_extract
-short_description: Manages SAP SAPCAR archives
-version_added: "0.1.0"
-description:
- - Provides support for unpacking C(sar)/C(car) files with the SAPCAR binary from SAP and pulling
- information back into Ansible.
-options:
- path:
- description: The path to the SAR/CAR file.
- type: path
- required: true
- dest:
- description:
- - The destination where SAPCAR extracts the SAR file. Missing folders will be created.
- If this parameter is not provided, it will unpack in the same folder as the SAR file.
- type: path
- binary_path:
- description:
- - The path to the SAPCAR binary, for example, C(/home/dummy/sapcar) or C(https://myserver/SAPCAR).
- If this parameter is not provided, the module will look in C(PATH).
- type: path
- signature:
- description:
- - If C(true), the signature will be extracted.
- default: false
- type: bool
- security_library:
- description:
- - The path to the security library, for example, C(/usr/sap/hostctrl/exe/libsapcrytp.so), for signature operations.
- type: path
- manifest:
- description:
- - The name of the manifest.
- default: "SIGNATURE.SMF"
- type: str
- remove:
- description:
- - If C(true), the SAR/CAR file will be removed. B(This should be used with caution!)
- default: false
- type: bool
-author:
- - Rainer Leber (@RainerLeber)
-notes:
- - Always returns C(changed=true) in C(check_mode).
-'''
-
-EXAMPLES = r"""
-- name: Extract SAR file
- community.sap.sapcar_extract:
- path: "~/source/hana.sar"
-
-- name: Extract SAR file with destination
- community.sap.sapcar_extract:
- path: "~/source/hana.sar"
- dest: "~/test/"
-
-- name: Extract SAR file with destination and download from webserver can be a fileshare as well
- community.sap.sapcar_extract:
- path: "~/source/hana.sar"
- dest: "~/dest/"
- binary_path: "https://myserver/SAPCAR"
-
-- name: Extract SAR file and delete SAR after extract
- community.sap.sapcar_extract:
- path: "~/source/hana.sar"
- remove: true
-
-- name: Extract SAR file with manifest
- community.sap.sapcar_extract:
- path: "~/source/hana.sar"
- signature: true
-
-- name: Extract SAR file with manifest and rename it
- community.sap.sapcar_extract:
- path: "~/source/hana.sar"
- manifest: "MyNewSignature.SMF"
- signature: true
-"""
-
-import os
-from tempfile import NamedTemporaryFile
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.urls import open_url
-from ansible.module_utils.common.text.converters import to_native
-
-
-def get_list_of_files(dir_name):
- # create a list of file and directories
- # names in the given directory
- list_of_file = os.listdir(dir_name)
- allFiles = list()
- # Iterate over all the entries
- for entry in list_of_file:
- # Create full path
- fullPath = os.path.join(dir_name, entry)
- # If entry is a directory then get the list of files in this directory
- if os.path.isdir(fullPath):
- allFiles = allFiles + [fullPath]
- allFiles = allFiles + get_list_of_files(fullPath)
- else:
- allFiles.append(fullPath)
- return allFiles
-
-
-def download_SAPCAR(binary_path, module):
- bin_path = None
- # download sapcar binary if url is provided otherwise path is returned
- if binary_path is not None:
- if binary_path.startswith('https://') or binary_path.startswith('http://'):
- random_file = NamedTemporaryFile(delete=False)
- with open_url(binary_path) as response:
- with random_file as out_file:
- data = response.read()
- out_file.write(data)
- os.chmod(out_file.name, 0o700)
- bin_path = out_file.name
- module.add_cleanup_file(bin_path)
- else:
- bin_path = binary_path
- return bin_path
-
-
-def check_if_present(command, path, dest, signature, manifest, module):
- # manipulating output from SAR file for compare with already extracted files
- iter_command = [command, '-tvf', path]
- sar_out = module.run_command(iter_command)[1]
- sar_raw = sar_out.split("\n")[1:]
- if dest[-1] != "/":
- dest = dest + "/"
- sar_files = [dest + x.split(" ")[-1] for x in sar_raw if x]
- # remove any SIGNATURE.SMF from list because it will not unpacked if signature is false
- if not signature:
- sar_files = [item for item in sar_files if not item.endswith('.SMF')]
- # if signature is renamed manipulate files in list of sar file for compare.
- if manifest != "SIGNATURE.SMF":
- sar_files = [item for item in sar_files if not item.endswith('.SMF')]
- sar_files = sar_files + [manifest]
- # get extracted files if present
- files_extracted = get_list_of_files(dest)
- # compare extracted files with files in sar file
- present = all(elem in files_extracted for elem in sar_files)
- return present
-
-
-def main():
- module = AnsibleModule(
- argument_spec=dict(
- path=dict(type='path', required=True),
- dest=dict(type='path'),
- binary_path=dict(type='path'),
- signature=dict(type='bool', default=False),
- security_library=dict(type='path'),
- manifest=dict(type='str', default="SIGNATURE.SMF"),
- remove=dict(type='bool', default=False),
- ),
- supports_check_mode=True,
- )
- rc, out, err = [0, "", ""]
- params = module.params
- check_mode = module.check_mode
-
- path = params['path']
- dest = params['dest']
- signature = params['signature']
- security_library = params['security_library']
- manifest = params['manifest']
- remove = params['remove']
-
- bin_path = download_SAPCAR(params['binary_path'], module)
-
- if dest is None:
- dest_head_tail = os.path.split(path)
- dest = dest_head_tail[0] + '/'
- else:
- if not os.path.exists(dest):
- os.makedirs(dest, 0o755)
-
- if bin_path is not None:
- command = [module.get_bin_path(bin_path, required=True)]
- else:
- try:
- command = [module.get_bin_path('sapcar', required=True)]
- except Exception as e:
- module.fail_json(msg='Failed to find SAPCAR at the expected path or URL "{0}". Please check whether it is available: {1}'
- .format(bin_path, to_native(e)))
-
- present = check_if_present(command[0], path, dest, signature, manifest, module)
-
- if not present:
- command.extend(['-xvf', path, '-R', dest])
- if security_library:
- command.extend(['-L', security_library])
- if signature:
- command.extend(['-manifest', manifest])
- if not check_mode:
- (rc, out, err) = module.run_command(command, check_rc=True)
- changed = True
- else:
- changed = False
- out = "already unpacked"
-
- if remove:
- os.remove(path)
-
- module.exit_json(changed=changed, message=rc, stdout=out,
- stderr=err, command=' '.join(command))
-
-
-if __name__ == '__main__':
- main()
diff --git a/ansible_collections/community/sap/plugins/modules/hana_query.py b/ansible_collections/community/sap/plugins/modules/hana_query.py
deleted file mode 100644
index 9eb43db09..000000000
--- a/ansible_collections/community/sap/plugins/modules/hana_query.py
+++ /dev/null
@@ -1,238 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-
-# Copyright: (c) 2021, Rainer Leber <rainerleber@gmail.com>
-# 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: hana_query
-short_description: Execute SQL on HANA
-version_added: "0.1.0"
-description: This module executes SQL statements on HANA with hdbsql.
-options:
- sid:
- description: The system ID.
- type: str
- required: false
- bin_path:
- description: The path to the hdbsql binary.
- type: str
- required: false
- instance:
- description: The instance number.
- type: str
- required: true
- user:
- description: A dedicated username. The user could be also in hdbuserstore.
- type: str
- default: SYSTEM
- userstore:
- description: If C(true), the user must be in hdbuserstore.
- type: bool
- default: false
- password:
- description:
- - The password to connect to the database.
- - "B(Note:) Since the passwords have to be passed as command line arguments, I(userstore=true) should
- be used whenever possible, as command line arguments can be seen by other users
- on the same machine."
- type: str
- autocommit:
- description: Autocommit the statement.
- type: bool
- default: true
- host:
- description: The Host IP address. The port can be defined as well.
- type: str
- database:
- description: Define the database on which to connect.
- type: str
- encrypted:
- description: Use encrypted connection.
- type: bool
- default: false
- filepath:
- description:
- - One or more files each containing one SQL query to run.
- - Must be a string or list containing strings.
- type: list
- elements: path
- query:
- description:
- - SQL query to run.
- - Must be a string or list containing strings. Please note that if you supply a string, it will be split by commas (C(,)) to a list.
- It is better to supply a one-element list instead to avoid mangled input.
- type: list
- elements: str
-notes:
- - Does not support C(check_mode). Always reports that the state has changed even if no changes have been made.
-author:
- - Rainer Leber (@rainerleber)
-'''
-
-EXAMPLES = r'''
-- name: Simple select query
- community.sap.hana_query:
- sid: "hdb"
- instance: "01"
- password: "Test123"
- query: select user_name from users
-
-- name: RUN select query with host port
- community.sap.hana_query:
- sid: "hdb"
- instance: "01"
- password: "Test123"
- host: "10.10.2.4:30001"
- query: select user_name from users
-
-- name: Run several queries
- community.sap.hana_query:
- sid: "hdb"
- instance: "01"
- password: "Test123"
- query:
- - select user_name from users
- - select * from SYSTEM
- host: "localhost"
- autocommit: False
-
-- name: Run several queries with path
- community.sap.hana_query:
- bin_path: "/usr/sap/HDB/HDB01/exe/hdbsql"
- instance: "01"
- password: "Test123"
- query:
- - select user_name from users
- - select * from users
- host: "localhost"
- autocommit: False
-
-- name: Run several queries from file
- community.sap.hana_query:
- sid: "hdb"
- instance: "01"
- password: "Test123"
- filepath:
- - /tmp/HANA_CPU_UtilizationPerCore_2.00.020+.txt
- - /tmp/HANA.txt
- host: "localhost"
-
-- name: Run several queries from user store
- community.sap.hana_query:
- sid: "hdb"
- instance: "01"
- user: hdbstoreuser
- userstore: true
- query:
- - select user_name from users
- - select * from users
- autocommit: False
-'''
-
-RETURN = r'''
-query_result:
- description: List containing results of all queries executed (one sublist for every query).
- returned: on success
- type: list
- elements: list
- sample: [[{"Column": "Value1"}, {"Column": "Value2"}], [{"Column": "Value1"}, {"Column": "Value2"}]]
-'''
-
-import csv
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.six import StringIO
-from ansible.module_utils.common.text.converters import to_native
-
-
-def csv_to_list(rawcsv):
- reader_raw = csv.DictReader(StringIO(rawcsv))
- reader = [dict((k, v.strip()) for k, v in row.items()) for row in reader_raw]
- return list(reader)
-
-
-def main():
- module = AnsibleModule(
- argument_spec=dict(
- sid=dict(type='str', required=False),
- bin_path=dict(type='str', required=False),
- instance=dict(type='str', required=True),
- encrypted=dict(type='bool', default=False),
- host=dict(type='str', required=False),
- user=dict(type='str', default="SYSTEM"),
- userstore=dict(type='bool', default=False),
- password=dict(type='str', no_log=True),
- database=dict(type='str', required=False),
- query=dict(type='list', elements='str', required=False),
- filepath=dict(type='list', elements='path', required=False),
- autocommit=dict(type='bool', default=True),
- ),
- required_one_of=[('query', 'filepath'), ('sid', 'instance')],
- required_if=[('userstore', False, ['password'])],
- supports_check_mode=False,
- )
- rc, out, err, out_raw = [0, [], "", ""]
-
- params = module.params
-
- sid = params['sid']
- bin_path = params['bin_path']
- instance = params['instance']
- user = params['user']
- userstore = params['userstore']
- password = params['password']
- autocommit = params['autocommit']
- host = params['host']
- database = params['database']
- encrypted = params['encrypted']
-
- filepath = params['filepath']
- query = params['query']
-
- if bin_path is None:
- bin_path = "/usr/sap/{sid}/HDB{instance}/exe/hdbsql".format(sid=sid.upper(), instance=instance)
-
- try:
- command = [module.get_bin_path(bin_path, required=True)]
- except Exception as e:
- module.fail_json(msg='Failed to find hdbsql at the expected path "{0}".Please check SID and instance number: "{1}"'.format(bin_path, to_native(e)))
-
- if encrypted is True:
- command.extend(['-attemptencrypt'])
- if autocommit is False:
- command.extend(['-z'])
- if host is not None:
- command.extend(['-n', host])
- if database is not None:
- command.extend(['-d', database])
- # -x Suppresses additional output, such as the number of selected rows in a result set.
- if userstore:
- command.extend(['-x', '-U', user])
- else:
- command.extend(['-x', '-i', instance, '-u', user, '-p', password])
-
- if filepath is not None:
- command.extend(['-I'])
- for p in filepath:
- # makes a command like hdbsql -i 01 -u SYSTEM -p secret123# -I /tmp/HANA_CPU_UtilizationPerCore_2.00.020+.txt,
- # iterates through files and append the output to var out.
- query_command = command + [p]
- (rc, out_raw, err) = module.run_command(query_command)
- out.append(csv_to_list(out_raw))
- if query is not None:
- for q in query:
- # makes a command like hdbsql -i 01 -u SYSTEM -p secret123# "select user_name from users",
- # iterates through multiple commands and append the output to var out.
- query_command = command + [q]
- (rc, out_raw, err) = module.run_command(query_command)
- out.append(csv_to_list(out_raw))
- changed = True
-
- module.exit_json(changed=changed, rc=rc, query_result=out, stderr=err)
-
-
-if __name__ == '__main__':
- main()
diff --git a/ansible_collections/community/sap/plugins/modules/identity/sap_company.py b/ansible_collections/community/sap/plugins/modules/identity/sap_company.py
deleted file mode 100644
index 8d3838e5f..000000000
--- a/ansible_collections/community/sap/plugins/modules/identity/sap_company.py
+++ /dev/null
@@ -1,326 +0,0 @@
-#!/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_company
-
-short_description: This module will manage a company entities in a SAP S4HANA environment
-
-version_added: "1.0.0"
-
-description:
- - The M(community.sap.sap_user) 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 company BAPIs C(BAPI_COMPANY_CLONE) and C(BAPI_COMPANY_DELETE) to manage company entities.
-
-options:
- state:
- description:
- - The decision what to do with the company.
- 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
- company_id:
- description: The company id.
- required: true
- type: str
- name:
- description: The company name.
- required: false
- type: str
- name_2:
- description: Additional company name.
- required: false
- type: str
- country:
- description: The country code for the company. For example, C('DE').
- required: false
- type: str
- time_zone:
- description: The timezone.
- required: false
- type: str
- city:
- description: The city where the company is located.
- required: false
- type: str
- post_code:
- description: The post code from the city.
- required: false
- type: str
- street:
- description: Street where the company is located.
- required: false
- type: str
- street_no:
- description: Street number.
- required: false
- type: str
- e_mail:
- description: General E-Mail address.
- required: false
- type: str
-
-requirements:
- - pyrfc >= 2.4.0
-
-author:
- - Rainer Leber (@rainerleber)
-
-notes:
- - Does not support C(check_mode).
-'''
-
-EXAMPLES = r'''
-- name: Create SAP Company
- community.sap.sap_company:
- conn_username: 'DDIC'
- conn_password: 'HECtna2021#'
- host: 100.0.201.20
- sysnr: '01'
- client: '000'
- state: present
- company_id: "Comp_ID"
- name: "Test_comp"
- name_2: "LTD"
- country: "DE"
- time_zone: "UTC"
- city: "City"
- post_code: "12345"
- street: "test_street"
- street_no: "1"
- e_mail: "test@test.de"
-
-# pass in a message and have changed true
-- name: Delete SAP Company
- community.sap.sap_company:
- conn_username: 'DDIC'
- conn_password: 'HECtna2021#'
- host: 100.0.201.20
- sysnr: '01'
- client: '000'
- state: absent
- company_id: "Comp_ID"
- name: "Test_comp"
- name_2: "LTD"
- country: "DE"
- time_zone: "UTC"
- city: "City"
- post_code: "12345"
- street: "test_street"
- street_no: "1"
- e_mail: "test@test.de"
-'''
-
-RETURN = r'''
-# These are examples of possible return values, and in general should use other names for return values.
-msg:
- description: A small execution description.
- type: str
- returned: always
- sample: 'Company address COMP_ID created'
-out:
- description: A complete description of the executed tasks. If this is available.
- type: list
- elements: dict
- returned: always
- sample: '{
- "RETURN": [
- {
- "FIELD": "",
- "ID": "01",
- "LOG_MSG_NO": "000000",
- "LOG_NO": "",
- "MESSAGE": "Company address COMP_ID created",
- "MESSAGE_V1": "COMP_ID",
- "MESSAGE_V2": "",
- "MESSAGE_V3": "",
- "MESSAGE_V4": "",
- "NUMBER": "078",
- "PARAMETER": "",
- "ROW": 0,
- "SYSTEM": "",
- "TYPE": "S"
- }
- ]
- }
- }'
-'''
-
-from ansible.module_utils.basic import AnsibleModule, missing_required_lib
-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 build_company_params(name, name_2, country, time_zone, city, post_code, street, street_no, e_mail):
- # Creates RFC parameters for creating organizations
- # define dicts in batch
- params = dict()
- # define company name
- params['NAME'] = name
- params['NAME_2'] = name_2
- # define location
- params['COUNTRY'] = country
- params['TIME_ZONE'] = time_zone
- params['CITY'] = city
- params['POSTL_COD1'] = post_code
- params['STREET'] = street
- params['STREET_NO'] = street_no
- # define communication
- params['E_MAIL'] = e_mail
- # return dict
- return params
-
-
-def return_analysis(raw):
- change = False
- failed = False
- msg = raw['RETURN'][0]['MESSAGE']
- for state in raw['RETURN']:
- if state['TYPE'] == "E":
- if state['NUMBER'] == '081':
- change = False
- else:
- failed = True
- if state['TYPE'] == "S":
- if state['NUMBER'] != '079':
- change = True
- else:
- msg = "No changes where made."
- return [{"change": change}, {"failed": failed}, {"msg": msg}]
-
-
-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"),
- company_id=dict(type='str', required=True),
- name=dict(type='str', required=False),
- name_2=dict(type='str', required=False),
- country=dict(type='str', required=False),
- time_zone=dict(type='str', required=False),
- city=dict(type='str', required=False),
- post_code=dict(type='str', required=False),
- street=dict(type='str', required=False),
- street_no=dict(type='str', required=False),
- e_mail=dict(type='str', required=False),
- ),
- supports_check_mode=False,
- )
- result = dict(changed=False, msg='', out={})
- raw = ""
-
- params = module.params
-
- state = params['state']
- conn_username = (params['conn_username']).upper()
- conn_password = params['conn_password']
- host = params['host']
- sysnr = params['sysnr']
- client = params['client']
-
- company_id = (params['company_id']).upper()
- name = params['name']
- name_2 = params['name_2']
- country = params['country']
- time_zone = params['time_zone']
- city = params['city']
- post_code = params['post_code']
- street = params['street']
- street_no = params['street_no']
- e_mail = params['e_mail']
-
- if not HAS_PYRFC_LIBRARY:
- module.fail_json(
- msg=missing_required_lib('pyrfc'),
- exception=ANOTHER_LIBRARY_IMPORT_ERROR)
-
- # 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)
-
- # build parameter dict of dict
- company_params = build_company_params(name, name_2, country, time_zone, city, post_code, street, street_no, e_mail)
-
- if state == "absent":
- raw = call_rfc_method(conn, 'BAPI_COMPANY_DELETE', {'COMPANY': company_id})
-
- if state == "present":
- raw = call_rfc_method(conn, 'BAPI_COMPANY_CLONE',
- {'METHOD': {'USMETHOD': 'COMPANY_CLONE'}, 'COMPANY': company_id, 'COMP_DATA': company_params})
-
- analysed = return_analysis(raw)
-
- result['out'] = raw
-
- result['changed'] = analysed[0]['change']
- result['msg'] = analysed[2]['msg']
-
- if analysed[1]['failed']:
- module.fail_json(**result)
-
- module.exit_json(**result)
-
-
-def main():
- run_module()
-
-
-if __name__ == '__main__':
- main()
diff --git a/ansible_collections/community/sap/plugins/modules/identity/sap_user.py b/ansible_collections/community/sap/plugins/modules/identity/sap_user.py
deleted file mode 100644
index f83472657..000000000
--- a/ansible_collections/community/sap/plugins/modules/identity/sap_user.py
+++ /dev/null
@@ -1,499 +0,0 @@
-#!/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_user
-short_description: This module will manage a user entities in a SAP S4/HANA environment
-version_added: "1.0.0"
-description:
- - The M(community.sap.sap_user) 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 following user BAPIs to manage user entities.
- - C(BAPI_USER_GET_DETAIL)
- - C(BAPI_USER_DELETE)
- - C(BAPI_USER_CREATE1)
- - C(BAPI_USER_CHANGE)
- - C(BAPI_USER_ACTGROUPS_ASSIGN)
- - C(BAPI_USER_PROFILES_ASSIGN)
- - C(BAPI_USER_UNLOCK)
- - C(BAPI_USER_LOCK)
-options:
- state:
- description:
- - The decision what to do with the user.
- default: 'present'
- choices:
- - 'present'
- - 'absent'
- - 'lock'
- - 'unlock'
- required: false
- type: str
- force:
- description:
- - Must be C('True') if the password or type should be overwritten.
- default: False
- required: false
- type: bool
- 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.
- default: '00'
- type: str
- client:
- description:
- - The client number to connect to.
- - You must quote the value to ensure retaining the leading zeros.
- default: '000'
- type: str
- username:
- description:
- - The username.
- type: str
- required: true
- firstname:
- description:
- - The Firstname of the user in the SAP system.
- type: str
- required: false
- lastname:
- description:
- - The lastname of the user in the SAP system.
- type: str
- required: false
- email:
- description:
- - The email address of the user in the SAP system.
- type: str
- required: false
- password:
- description:
- - The password for the user in the SAP system.
- type: str
- required: false
- useralias:
- description:
- - The alias for the user in the SAP system.
- type: str
- required: false
- user_type:
- description:
- - The type for the user in the SAP system.
- - C('A') Dialog user, C('B') System User, C('C') Communication User,
- C('S') Service User, C('L') Reference User.
- - Must be in uppercase.
- type: str
- required: false
- default: 'A'
- choices: ['A', 'B', 'C', 'S', 'L']
- company:
- description:
- - The specific company the user belongs to.
- - The company name must be available in the SAP system.
- type: str
- required: false
- profiles:
- description:
- - Assign profiles to the user.
- - Should be in uppercase, for example C('SAP_NEW') or C('SAP_ALL').
- type: list
- elements: str
- default: ['']
- required: false
- roles:
- description:
- - Assign roles to the user.
- type: list
- elements: str
- default: ['']
- required: false
-
-requirements:
- - pyrfc >= 2.4.0
-author:
- - Rainer Leber (@rainerleber)
-notes:
- - Does not support C(check_mode).
-'''
-
-EXAMPLES = r'''
-- name: Create SAP User
- community.sap.sap_user:
- conn_username: 'DDIC'
- conn_password: 'Test123'
- host: 192.168.1.150
- sysnr: '01'
- client: '000'
- state: present
- username: ADMIN
- firstname: first_admin
- lastname: last_admin
- email: admin@test.de
- password: Test123456
- useralias: ADMIN
- company: DEFAULT_COMPANY
- roles:
- - "SAP_ALL"
-
-- name: Force change SAP User
- community.sap.sap_user:
- conn_username: 'DDIC'
- conn_password: 'Test123'
- host: 192.168.1.150
- sysnr: '01'
- client: '000'
- state: present
- force: true
- username: ADMIN
- firstname: first_admin
- lastname: last_admin
- email: admin@test.de
- password: Test123456
- useralias: ADMIN
- company: DEFAULT_COMPANY
- roles:
- - "SAP_ALL"
-
-- name: Delete SAP User
- community.sap.sap_user:
- conn_username: 'DDIC'
- conn_password: 'Test123'
- host: 192.168.1.150
- sysnr: '01'
- client: '000'
- state: absent
- force: true
- username: ADMIN
-
-- name: Unlock SAP User
- community.sap.sap_user:
- conn_username: 'DDIC'
- conn_password: 'Test123'
- host: 192.168.1.150
- sysnr: '01'
- client: '000'
- state: unlock
- force: true
- username: ADMIN
-'''
-
-RETURN = r'''
-msg:
- description: A small execution description about the user action.
- type: str
- returned: always
- sample: 'User ADMIN created'
-out:
- description: A detailed description about the user action.
- type: list
- elements: dict
- returned: on success
- sample: [...,{
- "RETURN": [
- {
- "FIELD": "BNAME",
- "ID": "01",
- "LOG_MSG_NO": "000000",
- "LOG_NO": "",
- "MESSAGE": "User ADMIN created",
- "MESSAGE_V1": "ADMIN",
- "MESSAGE_V2": "",
- "MESSAGE_V3": "",
- "MESSAGE_V4": "",
- "NUMBER": "102",
- "PARAMETER": "",
- "ROW": 0,
- "SYSTEM": "",
- "TYPE": "S"
- }
- ],
- "SAPUSER_UUID_HIST": []}]
-'''
-from ansible.module_utils.basic import AnsibleModule, missing_required_lib
-import traceback
-import datetime
-try:
- from pyrfc import Connection
-except ImportError:
- HAS_PYRFC_LIBRARY = False
- PYRFC_LIBRARY_IMPORT_ERROR = traceback.format_exc()
-else:
- HAS_PYRFC_LIBRARY = True
-
-
-def add_to_dict(target_dict, target_key, value):
- # Adds the given value to a dict as the key
- # check if the given key is in the given dict yet
- if target_key in target_dict:
- return False
- target_dict[target_key] = value
- return True
-
-
-def call_rfc_method(connection, method_name, kwargs):
- # PyRFC call function
- return connection.call(method_name, **kwargs)
-
-
-def build_rfc_user_params(username, firstname, lastname, email, raw_password,
- useralias, user_type, raw_company, user_change, force):
- """Creates RFC parameters for Creating users"""
- # define dicts in batch
- params = dict()
- address = dict()
- password = dict()
- alias = dict()
- logondata = dict()
- company = dict()
- # for change parameters
- addressx = dict()
- passwordx = dict()
- logondatax = dict()
- companyx = dict()
- # define username
- add_to_dict(params, 'USERNAME', username)
- # define Address
- add_to_dict(address, 'FIRSTNAME', firstname)
- add_to_dict(address, 'LASTNAME', lastname)
- add_to_dict(address, 'E_MAIL', email)
- # define Password
- add_to_dict(password, 'BAPIPWD', raw_password)
- # define Alias
- add_to_dict(alias, 'USERALIAS', useralias)
- # define LogonData
- add_to_dict(logondata, 'GLTGV', datetime.date.today())
- add_to_dict(logondata, 'GLTGB', '20991231')
- add_to_dict(logondata, 'USTYP', user_type)
- # define company
- add_to_dict(company, 'COMPANY', raw_company)
- params['LOGONDATA'] = logondata
- params['ADDRESS'] = address
- params['COMPANY'] = company
- params['ALIAS'] = alias
- params['PASSWORD'] = password
- # add change if user exists
- if user_change and force:
- add_to_dict(addressx, 'FIRSTNAME', 'X')
- add_to_dict(addressx, 'LASTNAME', 'X')
- add_to_dict(addressx, 'E_MAIL', 'X')
- # define Password
- add_to_dict(passwordx, 'BAPIPWD', 'X')
- # define LogonData
- add_to_dict(logondatax, 'USTYP', 'X')
- # define company
- add_to_dict(companyx, 'COMPANY', 'X')
- params['LOGONDATAX'] = logondatax
- params['ADDRESSX'] = addressx
- params['COMPANYX'] = companyx
- params['PASSWORDX'] = passwordx
- return params
-
-
-def user_role_assignment_build_rfc_params(roles, username):
- rfc_table = []
-
- for role_name in roles:
- table_row = {'AGR_NAME': role_name}
-
- add_to_dict(table_row, 'FROM_DAT', datetime.date.today())
- add_to_dict(table_row, 'TO_DAT', '20991231')
-
- rfc_table.append(table_row)
-
- return {
- 'USERNAME': username,
- 'ACTIVITYGROUPS': rfc_table
- }
-
-
-def user_profile_assignment_build_rfc_params(profiles, username):
- rfc_table = []
-
- for profile_name in profiles:
- table_row = {'BAPIPROF': profile_name}
- rfc_table.append(table_row)
-
- return {
- 'USERNAME': username,
- 'PROFILES': rfc_table
- }
-
-
-def check_user(user_detail):
- if len(user_detail['RETURN']) > 0:
- for sub in user_detail['RETURN']:
- if sub['NUMBER'] == '124':
- return False
- return True
-
-
-def return_analysis(raw):
- change = False
- failed = False
- for state in raw['RETURN']:
- if state['TYPE'] == "E":
- if state['NUMBER'] == '224' or state['NUMBER'] == '124':
- change = False
- else:
- failed = True
- if state['TYPE'] == "S":
- if state['NUMBER'] != '029':
- change = True
- if state['TYPE'] == "W":
- if state['NUMBER'] == '049' or state['NUMBER'] == '047':
- change = True
- if state['NUMBER'] == '255':
- change = True
- return [{"change": change}, {"failed": failed}]
-
-
-def run_module():
- module = AnsibleModule(
- argument_spec=dict(
- # logical values
- state=dict(default='present', choices=[
- 'absent', 'present', 'lock', 'unlock']),
- force=dict(type='bool', default=False),
- # values for connection
- 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="00"),
- client=dict(type='str', default="000"),
- # values for the new or existing user
- username=dict(type='str', required=True),
- firstname=dict(type='str', required=False),
- lastname=dict(type='str', required=False),
- email=dict(type='str', required=False),
- password=dict(type='str', required=False, no_log=True),
- useralias=dict(type='str', required=False),
- user_type=dict(default="A",
- choices=['A', 'B', 'C', 'S', 'L']),
- company=dict(type='str', required=False),
- # values for profile must a list
- # Example ["SAP_NEW", "SAP_ALL"]
- profiles=dict(type='list', elements='str', default=[""]),
- # values for roles must a list
- roles=dict(type='list', elements='str', default=[""]),
- ),
- supports_check_mode=False,
- required_if=[('state', 'present', ['useralias', 'company'])]
- )
- result = dict(changed=False, msg='', out='')
- count = 0
- raw = ""
-
- params = module.params
-
- state = params['state']
- conn_username = (params['conn_username']).upper()
- conn_password = params['conn_password']
- host = params['host']
- sysnr = params['sysnr']
- client = params['client']
-
- username = (params['username']).upper()
- firstname = params['firstname']
- lastname = params['lastname']
- email = params['email']
- password = params['password']
- force = params['force']
- if not params['useralias'] is None:
- useralias = (params['useralias']).upper()
- user_type = (params['user_type']).upper()
- company = params['company']
-
- profiles = params['profiles']
- roles = params['roles']
-
- if not HAS_PYRFC_LIBRARY:
- module.fail_json(
- msg=missing_required_lib('pyrfc'),
- exception=PYRFC_LIBRARY_IMPORT_ERROR)
-
- # 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)
-
- # user details
- user_detail = call_rfc_method(conn, 'BAPI_USER_GET_DETAIL', {'USERNAME': username})
- user_exists = check_user(user_detail)
-
- if state == "absent":
- if user_exists:
- raw = call_rfc_method(conn, 'BAPI_USER_DELETE', {'USERNAME': username})
-
- if state == "present":
- user_params = build_rfc_user_params(username, firstname, lastname, email, password, useralias, user_type, company, user_exists, force)
- if not user_exists:
- raw = call_rfc_method(conn, 'BAPI_USER_CREATE1', user_params)
-
- if user_exists:
- # check for address changes when user exists
- user_no_changes = all((user_detail.get('ADDRESS')).get(k) == v for k, v in (user_params.get('ADDRESS')).items())
- if not user_no_changes or force:
- raw = call_rfc_method(conn, 'BAPI_USER_CHANGE', user_params)
-
- call_rfc_method(conn, 'BAPI_USER_ACTGROUPS_ASSIGN', user_role_assignment_build_rfc_params(roles, username))
-
- call_rfc_method(conn, 'BAPI_USER_PROFILES_ASSIGN', user_profile_assignment_build_rfc_params(profiles, username))
-
- if state == "unlock":
- if user_exists:
- raw = call_rfc_method(conn, 'BAPI_USER_UNLOCK', {'USERNAME': username})
-
- if state == "lock":
- if user_exists:
- raw = call_rfc_method(conn, 'BAPI_USER_LOCK', {'USERNAME': username})
-
- # analyse return value
- if raw != '':
- analysed = return_analysis(raw)
-
- result['out'] = raw
-
- result['changed'] = analysed[0]['change']
- for msgs in raw['RETURN']:
- if count > 0:
- result['msg'] = result['msg'] + '\n'
- result['msg'] = result['msg'] + msgs['MESSAGE']
- count = count + 1
-
- if analysed[1]['failed']:
- module.fail_json(**result)
- else:
- result['msg'] = "No changes where made."
-
- module.exit_json(**result)
-
-
-def main():
- run_module()
-
-
-if __name__ == '__main__':
- main()
diff --git a/ansible_collections/community/sap/plugins/modules/sap_company.py b/ansible_collections/community/sap/plugins/modules/sap_company.py
deleted file mode 100644
index 8d3838e5f..000000000
--- a/ansible_collections/community/sap/plugins/modules/sap_company.py
+++ /dev/null
@@ -1,326 +0,0 @@
-#!/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_company
-
-short_description: This module will manage a company entities in a SAP S4HANA environment
-
-version_added: "1.0.0"
-
-description:
- - The M(community.sap.sap_user) 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 company BAPIs C(BAPI_COMPANY_CLONE) and C(BAPI_COMPANY_DELETE) to manage company entities.
-
-options:
- state:
- description:
- - The decision what to do with the company.
- 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
- company_id:
- description: The company id.
- required: true
- type: str
- name:
- description: The company name.
- required: false
- type: str
- name_2:
- description: Additional company name.
- required: false
- type: str
- country:
- description: The country code for the company. For example, C('DE').
- required: false
- type: str
- time_zone:
- description: The timezone.
- required: false
- type: str
- city:
- description: The city where the company is located.
- required: false
- type: str
- post_code:
- description: The post code from the city.
- required: false
- type: str
- street:
- description: Street where the company is located.
- required: false
- type: str
- street_no:
- description: Street number.
- required: false
- type: str
- e_mail:
- description: General E-Mail address.
- required: false
- type: str
-
-requirements:
- - pyrfc >= 2.4.0
-
-author:
- - Rainer Leber (@rainerleber)
-
-notes:
- - Does not support C(check_mode).
-'''
-
-EXAMPLES = r'''
-- name: Create SAP Company
- community.sap.sap_company:
- conn_username: 'DDIC'
- conn_password: 'HECtna2021#'
- host: 100.0.201.20
- sysnr: '01'
- client: '000'
- state: present
- company_id: "Comp_ID"
- name: "Test_comp"
- name_2: "LTD"
- country: "DE"
- time_zone: "UTC"
- city: "City"
- post_code: "12345"
- street: "test_street"
- street_no: "1"
- e_mail: "test@test.de"
-
-# pass in a message and have changed true
-- name: Delete SAP Company
- community.sap.sap_company:
- conn_username: 'DDIC'
- conn_password: 'HECtna2021#'
- host: 100.0.201.20
- sysnr: '01'
- client: '000'
- state: absent
- company_id: "Comp_ID"
- name: "Test_comp"
- name_2: "LTD"
- country: "DE"
- time_zone: "UTC"
- city: "City"
- post_code: "12345"
- street: "test_street"
- street_no: "1"
- e_mail: "test@test.de"
-'''
-
-RETURN = r'''
-# These are examples of possible return values, and in general should use other names for return values.
-msg:
- description: A small execution description.
- type: str
- returned: always
- sample: 'Company address COMP_ID created'
-out:
- description: A complete description of the executed tasks. If this is available.
- type: list
- elements: dict
- returned: always
- sample: '{
- "RETURN": [
- {
- "FIELD": "",
- "ID": "01",
- "LOG_MSG_NO": "000000",
- "LOG_NO": "",
- "MESSAGE": "Company address COMP_ID created",
- "MESSAGE_V1": "COMP_ID",
- "MESSAGE_V2": "",
- "MESSAGE_V3": "",
- "MESSAGE_V4": "",
- "NUMBER": "078",
- "PARAMETER": "",
- "ROW": 0,
- "SYSTEM": "",
- "TYPE": "S"
- }
- ]
- }
- }'
-'''
-
-from ansible.module_utils.basic import AnsibleModule, missing_required_lib
-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 build_company_params(name, name_2, country, time_zone, city, post_code, street, street_no, e_mail):
- # Creates RFC parameters for creating organizations
- # define dicts in batch
- params = dict()
- # define company name
- params['NAME'] = name
- params['NAME_2'] = name_2
- # define location
- params['COUNTRY'] = country
- params['TIME_ZONE'] = time_zone
- params['CITY'] = city
- params['POSTL_COD1'] = post_code
- params['STREET'] = street
- params['STREET_NO'] = street_no
- # define communication
- params['E_MAIL'] = e_mail
- # return dict
- return params
-
-
-def return_analysis(raw):
- change = False
- failed = False
- msg = raw['RETURN'][0]['MESSAGE']
- for state in raw['RETURN']:
- if state['TYPE'] == "E":
- if state['NUMBER'] == '081':
- change = False
- else:
- failed = True
- if state['TYPE'] == "S":
- if state['NUMBER'] != '079':
- change = True
- else:
- msg = "No changes where made."
- return [{"change": change}, {"failed": failed}, {"msg": msg}]
-
-
-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"),
- company_id=dict(type='str', required=True),
- name=dict(type='str', required=False),
- name_2=dict(type='str', required=False),
- country=dict(type='str', required=False),
- time_zone=dict(type='str', required=False),
- city=dict(type='str', required=False),
- post_code=dict(type='str', required=False),
- street=dict(type='str', required=False),
- street_no=dict(type='str', required=False),
- e_mail=dict(type='str', required=False),
- ),
- supports_check_mode=False,
- )
- result = dict(changed=False, msg='', out={})
- raw = ""
-
- params = module.params
-
- state = params['state']
- conn_username = (params['conn_username']).upper()
- conn_password = params['conn_password']
- host = params['host']
- sysnr = params['sysnr']
- client = params['client']
-
- company_id = (params['company_id']).upper()
- name = params['name']
- name_2 = params['name_2']
- country = params['country']
- time_zone = params['time_zone']
- city = params['city']
- post_code = params['post_code']
- street = params['street']
- street_no = params['street_no']
- e_mail = params['e_mail']
-
- if not HAS_PYRFC_LIBRARY:
- module.fail_json(
- msg=missing_required_lib('pyrfc'),
- exception=ANOTHER_LIBRARY_IMPORT_ERROR)
-
- # 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)
-
- # build parameter dict of dict
- company_params = build_company_params(name, name_2, country, time_zone, city, post_code, street, street_no, e_mail)
-
- if state == "absent":
- raw = call_rfc_method(conn, 'BAPI_COMPANY_DELETE', {'COMPANY': company_id})
-
- if state == "present":
- raw = call_rfc_method(conn, 'BAPI_COMPANY_CLONE',
- {'METHOD': {'USMETHOD': 'COMPANY_CLONE'}, 'COMPANY': company_id, 'COMP_DATA': company_params})
-
- analysed = return_analysis(raw)
-
- result['out'] = raw
-
- result['changed'] = analysed[0]['change']
- result['msg'] = analysed[2]['msg']
-
- if analysed[1]['failed']:
- module.fail_json(**result)
-
- module.exit_json(**result)
-
-
-def main():
- run_module()
-
-
-if __name__ == '__main__':
- main()
diff --git a/ansible_collections/community/sap/plugins/modules/sap_snote.py b/ansible_collections/community/sap/plugins/modules/sap_snote.py
deleted file mode 100644
index 24f393927..000000000
--- a/ansible_collections/community/sap/plugins/modules/sap_snote.py
+++ /dev/null
@@ -1,258 +0,0 @@
-#!/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()
diff --git a/ansible_collections/community/sap/plugins/modules/sap_system_facts.py b/ansible_collections/community/sap/plugins/modules/sap_system_facts.py
deleted file mode 100644
index b5f4eb9b6..000000000
--- a/ansible_collections/community/sap/plugins/modules/sap_system_facts.py
+++ /dev/null
@@ -1,206 +0,0 @@
-#!/usr/bin/python
-
-# Copyright: (c) 2022, Rainer Leber rainerleber@gmail.com>
-# 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_system_facts
-
-short_description: Gathers SAP facts in a host
-
-version_added: "1.0.0"
-
-description:
- - This facts module gathers SAP system facts about the running instance.
-
-author:
- - Rainer Leber (@rainerleber)
-
-notes:
- - Supports C(check_mode).
-'''
-
-EXAMPLES = r'''
-- name: Return SAP system ansible_facts
- community.sap.sap_system_fact:
-'''
-
-RETURN = r'''
-# These are examples of possible return values,
-# and in general should use other names for return values.
-ansible_facts:
- description: Facts to add to ansible_facts.
- returned: always
- type: list
- elements: dict
- contains:
- sap:
- description: Facts about the running SAP system.
- type: list
- elements: dict
- returned: When SAP system fact is present
- sample: [
- {
- "InstanceType": "NW",
- "NR": "00",
- "SID": "ABC",
- "TYPE": "ASCS"
- },
- {
- "InstanceType": "NW",
- "NR": "01",
- "SID": "ABC",
- "TYPE": "PAS"
- },
- {
- "InstanceType": "HANA",
- "NR": "02",
- "SID": "HDB",
- "TYPE": "HDB"
- },
- {
- "InstanceType": "NW",
- "NR": "80",
- "SID": "WEB",
- "TYPE": "WebDisp"
- }
- ]
-'''
-
-from ansible.module_utils.basic import AnsibleModule
-import os
-import re
-
-
-def get_all_hana_sid():
- hana_sid = list()
- if os.path.isdir("/hana/shared"):
- # /hana/shared directory exists
- for sid in os.listdir('/hana/shared'):
- if os.path.isdir("/usr/sap/" + sid):
- hana_sid = hana_sid + [sid]
- if hana_sid:
- return hana_sid
-
-
-def get_all_nw_sid():
- nw_sid = list()
- if os.path.isdir("/sapmnt"):
- # /sapmnt directory exists
- for sid in os.listdir('/sapmnt'):
- if os.path.isdir("/usr/sap/" + sid):
- nw_sid = nw_sid + [sid]
- else:
- # Check to see if /sapmnt/SID/sap_bobj exists
- if os.path.isdir("/sapmnt/" + sid + "/sap_bobj"):
- # is a bobj system
- nw_sid = nw_sid + [sid]
- if nw_sid:
- return nw_sid
-
-
-def get_hana_nr(sids, module):
- hana_list = list()
- for sid in sids:
- for instance in os.listdir('/usr/sap/' + sid):
- if 'HDB' in instance:
- instance_nr = instance[-2:]
- # check if instance number exists
- command = [module.get_bin_path('/usr/sap/hostctrl/exe/sapcontrol', required=True)]
- command.extend(['-nr', instance_nr, '-function', 'GetProcessList'])
- check_instance = module.run_command(command, check_rc=False)
- # sapcontrol returns c(0 - 5) exit codes only c(1) is unavailable
- if check_instance[0] != 1:
- hana_list.append({'NR': instance_nr, 'SID': sid, 'TYPE': 'HDB', 'InstanceType': 'HANA'})
- return hana_list
-
-
-def get_nw_nr(sids, module):
- nw_list = list()
- type = ""
- for sid in sids:
- for instance in os.listdir('/usr/sap/' + sid):
- instance_nr = instance[-2:]
- command = [module.get_bin_path('/usr/sap/hostctrl/exe/sapcontrol', required=True)]
- # check if returned instance_nr is a number because sapcontrol returns all if a random string is provided
- if instance_nr.isdigit():
- command.extend(['-nr', instance_nr, '-function', 'GetInstanceProperties'])
- check_instance = module.run_command(command, check_rc=False)
- if check_instance[0] != 1:
- for line in check_instance[1].splitlines():
- if re.search('INSTANCE_NAME', line):
- # convert to list and extract last
- type_raw = (line.strip('][').split(', '))[-1]
- # split instance number
- type = type_raw[:-2]
- nw_list.append({'NR': instance_nr, 'SID': sid, 'TYPE': get_instance_type(type), 'InstanceType': 'NW'})
- return nw_list
-
-
-def get_instance_type(raw_type):
- if raw_type[0] == "D":
- # It's a PAS
- type = "PAS"
- elif raw_type[0] == "A":
- # It's an ASCS
- type = "ASCS"
- elif raw_type[0] == "W":
- # It's a Webdisp
- type = "WebDisp"
- elif raw_type[0] == "J":
- # It's a Java
- type = "Java"
- elif raw_type[0] == "S":
- # It's an SCS
- type = "SCS"
- elif raw_type[0] == "E":
- # It's an ERS
- type = "ERS"
- else:
- # Unknown instance type
- type = "XXX"
- return type
-
-
-def run_module():
- module_args = dict()
- system_result = list()
-
- result = dict(
- changed=False,
- ansible_facts=dict(),
- )
-
- module = AnsibleModule(
- argument_spec=module_args,
- supports_check_mode=True,
- )
-
- hana_sid = get_all_hana_sid()
- if hana_sid:
- system_result = system_result + get_hana_nr(hana_sid, module)
-
- nw_sid = get_all_nw_sid()
- if nw_sid:
- system_result = system_result + get_nw_nr(nw_sid, module)
-
- if system_result:
- result['ansible_facts'] = {'sap': system_result}
- else:
- result['ansible_facts']
-
- if module.check_mode:
- module.exit_json(**result)
-
- module.exit_json(**result)
-
-
-def main():
- run_module()
-
-
-if __name__ == '__main__':
- main()
diff --git a/ansible_collections/community/sap/plugins/modules/sap_task_list_execute.py b/ansible_collections/community/sap/plugins/modules/sap_task_list_execute.py
deleted file mode 100644
index 0ae25903f..000000000
--- a/ansible_collections/community/sap/plugins/modules/sap_task_list_execute.py
+++ /dev/null
@@ -1,340 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-
-# Copyright: (c) 2021, Rainer Leber <rainerleber@gmail.com>
-# 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_task_list_execute
-short_description: Perform SAP Task list execution
-version_added: "0.1.0"
-description:
- - The M(community.sap.sap_task_list_execute) 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.
- - Tasks in the task list which requires manual activities will be confirmed automatically.
- - This module will use the RFC package C(STC_TM_API).
-
-requirements:
- - pyrfc >= 2.4.0
- - xmltodict
-
-options:
- 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.
- default: '00'
- type: str
- client:
- description:
- - The client number to connect to.
- - You must quote the value to ensure retaining the leading zeros.
- default: '000'
- type: str
- task_to_execute:
- description: The task list which will be executed.
- required: true
- type: str
- task_parameters:
- description:
- - The tasks and the parameters for execution.
- - If the task list does not need any parameters, this could be empty.
- - If only specific tasks from the task list should be executed,
- the tasks even when no parameter is needed must be provided
- alongside with the module parameter I(task_skip=true).
- type: list
- elements: dict
- suboptions:
- TASKNAME:
- description: The name of the task in the task list.
- type: str
- required: true
- FIELDNAME:
- description: The name of the field of the task.
- type: str
- VALUE:
- description: The value which have to be set.
- type: raw
- task_settings:
- description:
- - Setting for the execution of the task list. This can be the following as in TCODE SE80 described.
- Check Mode C(CHECKRUN), Background Processing Active C(BATCH) (this is the default value),
- Asynchronous Execution C(ASYNC), Trace Mode C(TRACE), Server Name C(BATCH_TARGET).
- default: ['BATCH']
- type: list
- elements: str
- task_skip:
- description:
- - If this parameter is C(true), not defined tasks in I(task_parameters) are skipped.
- - This could be the case when only certain tasks should run from the task list.
- default: false
- type: bool
-
-notes:
- - Does not support C(check_mode). Always returns that the state has changed.
-author:
- - Rainer Leber (@rainerleber)
-'''
-
-EXAMPLES = r'''
-# Pass in a message
-- name: Test task execution
- community.sap.sap_task_list_execute:
- conn_username: DDIC
- conn_password: Passwd1234
- host: 10.1.8.10
- sysnr: '01'
- client: '000'
- task_to_execute: SAP_BASIS_SSL_CHECK
- task_settings: batch
-
-- name: Pass in input parameters
- community.sap.sap_task_list_execute:
- conn_username: DDIC
- conn_password: Passwd1234
- host: 10.1.8.10
- sysnr: '00'
- client: '000'
- task_to_execute: SAP_BASIS_SSL_CHECK
- task_parameters :
- - { 'TASKNAME': 'CL_STCT_CHECK_SEC_CRYPTO', 'FIELDNAME': 'P_OPT2', 'VALUE': 'X' }
- - TASKNAME: CL_STCT_CHECK_SEC_CRYPTO
- FIELDNAME: P_OPT3
- VALUE: X
- task_settings: batch
-
-# Exported environment variables
-- name: Hint if module will fail with error message like ImportError libsapnwrfc.so...
- community.sap.sap_task_list_execute:
- conn_username: DDIC
- conn_password: Passwd1234
- host: 10.1.8.10
- sysnr: '00'
- client: '000'
- task_to_execute: SAP_BASIS_SSL_CHECK
- task_settings: batch
- environment:
- SAPNWRFC_HOME: /usr/local/sap/nwrfcsdk
- LD_LIBRARY_PATH: /usr/local/sap/nwrfcsdk/lib
-'''
-
-RETURN = r'''
-msg:
- description: A small execution description.
- type: str
- returned: always
- sample: 'Successful'
-out:
- description: A complete description of the executed tasks. If this is available.
- type: list
- elements: dict
- returned: on success
- sample: [...,{
- "LOG": {
- "STCTM_S_LOG": [
- {
- "ACTIVITY": "U_CONFIG",
- "ACTIVITY_DESCR": "Configuration changed",
- "DETAILS": null,
- "EXEC_ID": "20210728184903.815739",
- "FIELD": null,
- "ID": "STC_TASK",
- "LOG_MSG_NO": "000000",
- "LOG_NO": null,
- "MESSAGE": "For radiobutton group ICM too many options are set; choose only one option",
- "MESSAGE_V1": "ICM",
- "MESSAGE_V2": null,
- "MESSAGE_V3": null,
- "MESSAGE_V4": null,
- "NUMBER": "048",
- "PARAMETER": null,
- "PERIOD": "M",
- "PERIOD_DESCR": "Maintenance",
- "ROW": "0",
- "SRC_LINE": "170",
- "SRC_OBJECT": "CL_STCTM_REPORT_UI IF_STCTM_UI_TASK~SET_PARAMETERS",
- "SYSTEM": null,
- "TIMESTMP": "20210728184903",
- "TSTPNM": "DDIC",
- "TYPE": "E"
- },...
- ]}}]
-'''
-
-from ansible.module_utils.basic import AnsibleModule, missing_required_lib
-import traceback
-try:
- from pyrfc import Connection
-except ImportError:
- HAS_PYRFC_LIBRARY = False
- PYRFC_LIBRARY_IMPORT_ERROR = traceback.format_exc()
-else:
- HAS_PYRFC_LIBRARY = True
-try:
- import xmltodict
-except ImportError:
- HAS_XMLTODICT_LIBRARY = False
- XMLTODICT_LIBRARY_IMPORT_ERROR = traceback.format_exc()
-else:
- HAS_XMLTODICT_LIBRARY = True
-
-
-def call_rfc_method(connection, method_name, kwargs):
- # PyRFC call function
- return connection.call(method_name, **kwargs)
-
-
-def process_exec_settings(task_settings):
- # processes task settings to objects
- exec_settings = {}
- for settings in task_settings:
- temp_dict = {settings.upper(): 'X'}
- for key, value in temp_dict.items():
- exec_settings[key] = value
- return exec_settings
-
-
-def xml_to_dict(xml_raw):
- try:
- xml_parsed = xmltodict.parse(xml_raw, dict_constructor=dict)
- xml_dict = xml_parsed['asx:abap']['asx:values']['SESSION']['TASKLIST']
- except KeyError:
- xml_dict = "No logs available."
- return xml_dict
-
-
-def run_module():
-
- params_spec = dict(
- TASKNAME=dict(type='str', required=True),
- FIELDNAME=dict(type='str'),
- VALUE=dict(type='raw'),
- )
-
- # define available arguments/parameters a user can pass to the module
- module = AnsibleModule(
- argument_spec=dict(
- # values for connection
- 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="00"),
- client=dict(type='str', default="000"),
- # values for execution tasks
- task_to_execute=dict(type='str', required=True),
- task_parameters=dict(type='list', elements='dict', options=params_spec),
- task_settings=dict(type='list', elements='str', default=['BATCH']),
- task_skip=dict(type='bool', default=False),
- ),
- supports_check_mode=False,
- )
- result = dict(changed=False, msg='', out={})
-
- params = module.params
-
- username = params['conn_username'].upper()
- password = params['conn_password']
- host = params['host']
- sysnr = params['sysnr']
- client = params['client']
-
- task_parameters = params['task_parameters']
- task_to_execute = params['task_to_execute']
- task_settings = params['task_settings']
- task_skip = params['task_skip']
-
- if not HAS_PYRFC_LIBRARY:
- module.fail_json(
- msg=missing_required_lib('pyrfc'),
- exception=PYRFC_LIBRARY_IMPORT_ERROR)
-
- if not HAS_XMLTODICT_LIBRARY:
- module.fail_json(
- msg=missing_required_lib('xmltodict'),
- exception=XMLTODICT_LIBRARY_IMPORT_ERROR)
-
- # basic RFC connection with pyrfc
- try:
- conn = Connection(user=username, passwd=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)
-
- try:
- raw_params = call_rfc_method(conn, 'STC_TM_SCENARIO_GET_PARAMETERS',
- {'I_SCENARIO_ID': task_to_execute})
- except Exception as err:
- result['error'] = str(err)
- result['msg'] = 'The task list does not exist.'
- module.fail_json(**result)
- exec_settings = process_exec_settings(task_settings)
- # initialize session task
- session_init = call_rfc_method(conn, 'STC_TM_SESSION_BEGIN',
- {'I_SCENARIO_ID': task_to_execute,
- 'I_INIT_ONLY': 'X'})
- # Confirm Tasks which requires manual activities from Task List Run
- for task in raw_params['ET_PARAMETER']:
- call_rfc_method(conn, 'STC_TM_TASK_CONFIRM',
- {'I_SESSION_ID': session_init['E_SESSION_ID'],
- 'I_TASKNAME': task['TASKNAME']})
- if task_skip:
- for task in raw_params['ET_PARAMETER']:
- call_rfc_method(conn, 'STC_TM_TASK_SKIP',
- {'I_SESSION_ID': session_init['E_SESSION_ID'],
- 'I_TASKNAME': task['TASKNAME'], 'I_SKIP_DEP_TASKS': 'X'})
- # unskip defined tasks and set parameters
- if task_parameters is not None:
- for task in task_parameters:
- call_rfc_method(conn, 'STC_TM_TASK_UNSKIP',
- {'I_SESSION_ID': session_init['E_SESSION_ID'],
- 'I_TASKNAME': task['TASKNAME'], 'I_UNSKIP_DEP_TASKS': 'X'})
-
- call_rfc_method(conn, 'STC_TM_SESSION_SET_PARAMETERS',
- {'I_SESSION_ID': session_init['E_SESSION_ID'],
- 'IT_PARAMETER': task_parameters})
- # start the task
- try:
- session_start = call_rfc_method(conn, 'STC_TM_SESSION_RESUME',
- {'I_SESSION_ID': session_init['E_SESSION_ID'],
- 'IS_EXEC_SETTINGS': exec_settings})
- except Exception as err:
- result['error'] = str(err)
- result['msg'] = 'Something went wrong. See error.'
- module.fail_json(**result)
- # get task logs because the execution may successfully but the tasks shows errors or warnings
- # returned value is ABAPXML https://help.sap.com/doc/abapdocu_755_index_htm/7.55/en-US/abenabap_xslt_asxml_general.htm
- session_log = call_rfc_method(conn, 'STC_TM_SESSION_GET_LOG',
- {'I_SESSION_ID': session_init['E_SESSION_ID']})
-
- task_list = xml_to_dict(session_log['E_LOG'])
-
- result['changed'] = True
- result['msg'] = session_start['E_STATUS_DESCR']
- result['out'] = task_list
-
- module.exit_json(**result)
-
-
-def main():
- run_module()
-
-
-if __name__ == '__main__':
- main()
diff --git a/ansible_collections/community/sap/plugins/modules/sap_user.py b/ansible_collections/community/sap/plugins/modules/sap_user.py
deleted file mode 100644
index f83472657..000000000
--- a/ansible_collections/community/sap/plugins/modules/sap_user.py
+++ /dev/null
@@ -1,499 +0,0 @@
-#!/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_user
-short_description: This module will manage a user entities in a SAP S4/HANA environment
-version_added: "1.0.0"
-description:
- - The M(community.sap.sap_user) 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 following user BAPIs to manage user entities.
- - C(BAPI_USER_GET_DETAIL)
- - C(BAPI_USER_DELETE)
- - C(BAPI_USER_CREATE1)
- - C(BAPI_USER_CHANGE)
- - C(BAPI_USER_ACTGROUPS_ASSIGN)
- - C(BAPI_USER_PROFILES_ASSIGN)
- - C(BAPI_USER_UNLOCK)
- - C(BAPI_USER_LOCK)
-options:
- state:
- description:
- - The decision what to do with the user.
- default: 'present'
- choices:
- - 'present'
- - 'absent'
- - 'lock'
- - 'unlock'
- required: false
- type: str
- force:
- description:
- - Must be C('True') if the password or type should be overwritten.
- default: False
- required: false
- type: bool
- 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.
- default: '00'
- type: str
- client:
- description:
- - The client number to connect to.
- - You must quote the value to ensure retaining the leading zeros.
- default: '000'
- type: str
- username:
- description:
- - The username.
- type: str
- required: true
- firstname:
- description:
- - The Firstname of the user in the SAP system.
- type: str
- required: false
- lastname:
- description:
- - The lastname of the user in the SAP system.
- type: str
- required: false
- email:
- description:
- - The email address of the user in the SAP system.
- type: str
- required: false
- password:
- description:
- - The password for the user in the SAP system.
- type: str
- required: false
- useralias:
- description:
- - The alias for the user in the SAP system.
- type: str
- required: false
- user_type:
- description:
- - The type for the user in the SAP system.
- - C('A') Dialog user, C('B') System User, C('C') Communication User,
- C('S') Service User, C('L') Reference User.
- - Must be in uppercase.
- type: str
- required: false
- default: 'A'
- choices: ['A', 'B', 'C', 'S', 'L']
- company:
- description:
- - The specific company the user belongs to.
- - The company name must be available in the SAP system.
- type: str
- required: false
- profiles:
- description:
- - Assign profiles to the user.
- - Should be in uppercase, for example C('SAP_NEW') or C('SAP_ALL').
- type: list
- elements: str
- default: ['']
- required: false
- roles:
- description:
- - Assign roles to the user.
- type: list
- elements: str
- default: ['']
- required: false
-
-requirements:
- - pyrfc >= 2.4.0
-author:
- - Rainer Leber (@rainerleber)
-notes:
- - Does not support C(check_mode).
-'''
-
-EXAMPLES = r'''
-- name: Create SAP User
- community.sap.sap_user:
- conn_username: 'DDIC'
- conn_password: 'Test123'
- host: 192.168.1.150
- sysnr: '01'
- client: '000'
- state: present
- username: ADMIN
- firstname: first_admin
- lastname: last_admin
- email: admin@test.de
- password: Test123456
- useralias: ADMIN
- company: DEFAULT_COMPANY
- roles:
- - "SAP_ALL"
-
-- name: Force change SAP User
- community.sap.sap_user:
- conn_username: 'DDIC'
- conn_password: 'Test123'
- host: 192.168.1.150
- sysnr: '01'
- client: '000'
- state: present
- force: true
- username: ADMIN
- firstname: first_admin
- lastname: last_admin
- email: admin@test.de
- password: Test123456
- useralias: ADMIN
- company: DEFAULT_COMPANY
- roles:
- - "SAP_ALL"
-
-- name: Delete SAP User
- community.sap.sap_user:
- conn_username: 'DDIC'
- conn_password: 'Test123'
- host: 192.168.1.150
- sysnr: '01'
- client: '000'
- state: absent
- force: true
- username: ADMIN
-
-- name: Unlock SAP User
- community.sap.sap_user:
- conn_username: 'DDIC'
- conn_password: 'Test123'
- host: 192.168.1.150
- sysnr: '01'
- client: '000'
- state: unlock
- force: true
- username: ADMIN
-'''
-
-RETURN = r'''
-msg:
- description: A small execution description about the user action.
- type: str
- returned: always
- sample: 'User ADMIN created'
-out:
- description: A detailed description about the user action.
- type: list
- elements: dict
- returned: on success
- sample: [...,{
- "RETURN": [
- {
- "FIELD": "BNAME",
- "ID": "01",
- "LOG_MSG_NO": "000000",
- "LOG_NO": "",
- "MESSAGE": "User ADMIN created",
- "MESSAGE_V1": "ADMIN",
- "MESSAGE_V2": "",
- "MESSAGE_V3": "",
- "MESSAGE_V4": "",
- "NUMBER": "102",
- "PARAMETER": "",
- "ROW": 0,
- "SYSTEM": "",
- "TYPE": "S"
- }
- ],
- "SAPUSER_UUID_HIST": []}]
-'''
-from ansible.module_utils.basic import AnsibleModule, missing_required_lib
-import traceback
-import datetime
-try:
- from pyrfc import Connection
-except ImportError:
- HAS_PYRFC_LIBRARY = False
- PYRFC_LIBRARY_IMPORT_ERROR = traceback.format_exc()
-else:
- HAS_PYRFC_LIBRARY = True
-
-
-def add_to_dict(target_dict, target_key, value):
- # Adds the given value to a dict as the key
- # check if the given key is in the given dict yet
- if target_key in target_dict:
- return False
- target_dict[target_key] = value
- return True
-
-
-def call_rfc_method(connection, method_name, kwargs):
- # PyRFC call function
- return connection.call(method_name, **kwargs)
-
-
-def build_rfc_user_params(username, firstname, lastname, email, raw_password,
- useralias, user_type, raw_company, user_change, force):
- """Creates RFC parameters for Creating users"""
- # define dicts in batch
- params = dict()
- address = dict()
- password = dict()
- alias = dict()
- logondata = dict()
- company = dict()
- # for change parameters
- addressx = dict()
- passwordx = dict()
- logondatax = dict()
- companyx = dict()
- # define username
- add_to_dict(params, 'USERNAME', username)
- # define Address
- add_to_dict(address, 'FIRSTNAME', firstname)
- add_to_dict(address, 'LASTNAME', lastname)
- add_to_dict(address, 'E_MAIL', email)
- # define Password
- add_to_dict(password, 'BAPIPWD', raw_password)
- # define Alias
- add_to_dict(alias, 'USERALIAS', useralias)
- # define LogonData
- add_to_dict(logondata, 'GLTGV', datetime.date.today())
- add_to_dict(logondata, 'GLTGB', '20991231')
- add_to_dict(logondata, 'USTYP', user_type)
- # define company
- add_to_dict(company, 'COMPANY', raw_company)
- params['LOGONDATA'] = logondata
- params['ADDRESS'] = address
- params['COMPANY'] = company
- params['ALIAS'] = alias
- params['PASSWORD'] = password
- # add change if user exists
- if user_change and force:
- add_to_dict(addressx, 'FIRSTNAME', 'X')
- add_to_dict(addressx, 'LASTNAME', 'X')
- add_to_dict(addressx, 'E_MAIL', 'X')
- # define Password
- add_to_dict(passwordx, 'BAPIPWD', 'X')
- # define LogonData
- add_to_dict(logondatax, 'USTYP', 'X')
- # define company
- add_to_dict(companyx, 'COMPANY', 'X')
- params['LOGONDATAX'] = logondatax
- params['ADDRESSX'] = addressx
- params['COMPANYX'] = companyx
- params['PASSWORDX'] = passwordx
- return params
-
-
-def user_role_assignment_build_rfc_params(roles, username):
- rfc_table = []
-
- for role_name in roles:
- table_row = {'AGR_NAME': role_name}
-
- add_to_dict(table_row, 'FROM_DAT', datetime.date.today())
- add_to_dict(table_row, 'TO_DAT', '20991231')
-
- rfc_table.append(table_row)
-
- return {
- 'USERNAME': username,
- 'ACTIVITYGROUPS': rfc_table
- }
-
-
-def user_profile_assignment_build_rfc_params(profiles, username):
- rfc_table = []
-
- for profile_name in profiles:
- table_row = {'BAPIPROF': profile_name}
- rfc_table.append(table_row)
-
- return {
- 'USERNAME': username,
- 'PROFILES': rfc_table
- }
-
-
-def check_user(user_detail):
- if len(user_detail['RETURN']) > 0:
- for sub in user_detail['RETURN']:
- if sub['NUMBER'] == '124':
- return False
- return True
-
-
-def return_analysis(raw):
- change = False
- failed = False
- for state in raw['RETURN']:
- if state['TYPE'] == "E":
- if state['NUMBER'] == '224' or state['NUMBER'] == '124':
- change = False
- else:
- failed = True
- if state['TYPE'] == "S":
- if state['NUMBER'] != '029':
- change = True
- if state['TYPE'] == "W":
- if state['NUMBER'] == '049' or state['NUMBER'] == '047':
- change = True
- if state['NUMBER'] == '255':
- change = True
- return [{"change": change}, {"failed": failed}]
-
-
-def run_module():
- module = AnsibleModule(
- argument_spec=dict(
- # logical values
- state=dict(default='present', choices=[
- 'absent', 'present', 'lock', 'unlock']),
- force=dict(type='bool', default=False),
- # values for connection
- 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="00"),
- client=dict(type='str', default="000"),
- # values for the new or existing user
- username=dict(type='str', required=True),
- firstname=dict(type='str', required=False),
- lastname=dict(type='str', required=False),
- email=dict(type='str', required=False),
- password=dict(type='str', required=False, no_log=True),
- useralias=dict(type='str', required=False),
- user_type=dict(default="A",
- choices=['A', 'B', 'C', 'S', 'L']),
- company=dict(type='str', required=False),
- # values for profile must a list
- # Example ["SAP_NEW", "SAP_ALL"]
- profiles=dict(type='list', elements='str', default=[""]),
- # values for roles must a list
- roles=dict(type='list', elements='str', default=[""]),
- ),
- supports_check_mode=False,
- required_if=[('state', 'present', ['useralias', 'company'])]
- )
- result = dict(changed=False, msg='', out='')
- count = 0
- raw = ""
-
- params = module.params
-
- state = params['state']
- conn_username = (params['conn_username']).upper()
- conn_password = params['conn_password']
- host = params['host']
- sysnr = params['sysnr']
- client = params['client']
-
- username = (params['username']).upper()
- firstname = params['firstname']
- lastname = params['lastname']
- email = params['email']
- password = params['password']
- force = params['force']
- if not params['useralias'] is None:
- useralias = (params['useralias']).upper()
- user_type = (params['user_type']).upper()
- company = params['company']
-
- profiles = params['profiles']
- roles = params['roles']
-
- if not HAS_PYRFC_LIBRARY:
- module.fail_json(
- msg=missing_required_lib('pyrfc'),
- exception=PYRFC_LIBRARY_IMPORT_ERROR)
-
- # 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)
-
- # user details
- user_detail = call_rfc_method(conn, 'BAPI_USER_GET_DETAIL', {'USERNAME': username})
- user_exists = check_user(user_detail)
-
- if state == "absent":
- if user_exists:
- raw = call_rfc_method(conn, 'BAPI_USER_DELETE', {'USERNAME': username})
-
- if state == "present":
- user_params = build_rfc_user_params(username, firstname, lastname, email, password, useralias, user_type, company, user_exists, force)
- if not user_exists:
- raw = call_rfc_method(conn, 'BAPI_USER_CREATE1', user_params)
-
- if user_exists:
- # check for address changes when user exists
- user_no_changes = all((user_detail.get('ADDRESS')).get(k) == v for k, v in (user_params.get('ADDRESS')).items())
- if not user_no_changes or force:
- raw = call_rfc_method(conn, 'BAPI_USER_CHANGE', user_params)
-
- call_rfc_method(conn, 'BAPI_USER_ACTGROUPS_ASSIGN', user_role_assignment_build_rfc_params(roles, username))
-
- call_rfc_method(conn, 'BAPI_USER_PROFILES_ASSIGN', user_profile_assignment_build_rfc_params(profiles, username))
-
- if state == "unlock":
- if user_exists:
- raw = call_rfc_method(conn, 'BAPI_USER_UNLOCK', {'USERNAME': username})
-
- if state == "lock":
- if user_exists:
- raw = call_rfc_method(conn, 'BAPI_USER_LOCK', {'USERNAME': username})
-
- # analyse return value
- if raw != '':
- analysed = return_analysis(raw)
-
- result['out'] = raw
-
- result['changed'] = analysed[0]['change']
- for msgs in raw['RETURN']:
- if count > 0:
- result['msg'] = result['msg'] + '\n'
- result['msg'] = result['msg'] + msgs['MESSAGE']
- count = count + 1
-
- if analysed[1]['failed']:
- module.fail_json(**result)
- else:
- result['msg'] = "No changes where made."
-
- module.exit_json(**result)
-
-
-def main():
- run_module()
-
-
-if __name__ == '__main__':
- main()
diff --git a/ansible_collections/community/sap/plugins/modules/sapcar_extract.py b/ansible_collections/community/sap/plugins/modules/sapcar_extract.py
deleted file mode 100644
index d586dd330..000000000
--- a/ansible_collections/community/sap/plugins/modules/sapcar_extract.py
+++ /dev/null
@@ -1,220 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-
-# Copyright: (c) 2021, Rainer Leber <rainerleber@gmail.com>
-# 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: sapcar_extract
-short_description: Manages SAP SAPCAR archives
-version_added: "0.1.0"
-description:
- - Provides support for unpacking C(sar)/C(car) files with the SAPCAR binary from SAP and pulling
- information back into Ansible.
-options:
- path:
- description: The path to the SAR/CAR file.
- type: path
- required: true
- dest:
- description:
- - The destination where SAPCAR extracts the SAR file. Missing folders will be created.
- If this parameter is not provided, it will unpack in the same folder as the SAR file.
- type: path
- binary_path:
- description:
- - The path to the SAPCAR binary, for example, C(/home/dummy/sapcar) or C(https://myserver/SAPCAR).
- If this parameter is not provided, the module will look in C(PATH).
- type: path
- signature:
- description:
- - If C(true), the signature will be extracted.
- default: false
- type: bool
- security_library:
- description:
- - The path to the security library, for example, C(/usr/sap/hostctrl/exe/libsapcrytp.so), for signature operations.
- type: path
- manifest:
- description:
- - The name of the manifest.
- default: "SIGNATURE.SMF"
- type: str
- remove:
- description:
- - If C(true), the SAR/CAR file will be removed. B(This should be used with caution!)
- default: false
- type: bool
-author:
- - Rainer Leber (@RainerLeber)
-notes:
- - Always returns C(changed=true) in C(check_mode).
-'''
-
-EXAMPLES = r"""
-- name: Extract SAR file
- community.sap.sapcar_extract:
- path: "~/source/hana.sar"
-
-- name: Extract SAR file with destination
- community.sap.sapcar_extract:
- path: "~/source/hana.sar"
- dest: "~/test/"
-
-- name: Extract SAR file with destination and download from webserver can be a fileshare as well
- community.sap.sapcar_extract:
- path: "~/source/hana.sar"
- dest: "~/dest/"
- binary_path: "https://myserver/SAPCAR"
-
-- name: Extract SAR file and delete SAR after extract
- community.sap.sapcar_extract:
- path: "~/source/hana.sar"
- remove: true
-
-- name: Extract SAR file with manifest
- community.sap.sapcar_extract:
- path: "~/source/hana.sar"
- signature: true
-
-- name: Extract SAR file with manifest and rename it
- community.sap.sapcar_extract:
- path: "~/source/hana.sar"
- manifest: "MyNewSignature.SMF"
- signature: true
-"""
-
-import os
-from tempfile import NamedTemporaryFile
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.urls import open_url
-from ansible.module_utils.common.text.converters import to_native
-
-
-def get_list_of_files(dir_name):
- # create a list of file and directories
- # names in the given directory
- list_of_file = os.listdir(dir_name)
- allFiles = list()
- # Iterate over all the entries
- for entry in list_of_file:
- # Create full path
- fullPath = os.path.join(dir_name, entry)
- # If entry is a directory then get the list of files in this directory
- if os.path.isdir(fullPath):
- allFiles = allFiles + [fullPath]
- allFiles = allFiles + get_list_of_files(fullPath)
- else:
- allFiles.append(fullPath)
- return allFiles
-
-
-def download_SAPCAR(binary_path, module):
- bin_path = None
- # download sapcar binary if url is provided otherwise path is returned
- if binary_path is not None:
- if binary_path.startswith('https://') or binary_path.startswith('http://'):
- random_file = NamedTemporaryFile(delete=False)
- with open_url(binary_path) as response:
- with random_file as out_file:
- data = response.read()
- out_file.write(data)
- os.chmod(out_file.name, 0o700)
- bin_path = out_file.name
- module.add_cleanup_file(bin_path)
- else:
- bin_path = binary_path
- return bin_path
-
-
-def check_if_present(command, path, dest, signature, manifest, module):
- # manipulating output from SAR file for compare with already extracted files
- iter_command = [command, '-tvf', path]
- sar_out = module.run_command(iter_command)[1]
- sar_raw = sar_out.split("\n")[1:]
- if dest[-1] != "/":
- dest = dest + "/"
- sar_files = [dest + x.split(" ")[-1] for x in sar_raw if x]
- # remove any SIGNATURE.SMF from list because it will not unpacked if signature is false
- if not signature:
- sar_files = [item for item in sar_files if not item.endswith('.SMF')]
- # if signature is renamed manipulate files in list of sar file for compare.
- if manifest != "SIGNATURE.SMF":
- sar_files = [item for item in sar_files if not item.endswith('.SMF')]
- sar_files = sar_files + [manifest]
- # get extracted files if present
- files_extracted = get_list_of_files(dest)
- # compare extracted files with files in sar file
- present = all(elem in files_extracted for elem in sar_files)
- return present
-
-
-def main():
- module = AnsibleModule(
- argument_spec=dict(
- path=dict(type='path', required=True),
- dest=dict(type='path'),
- binary_path=dict(type='path'),
- signature=dict(type='bool', default=False),
- security_library=dict(type='path'),
- manifest=dict(type='str', default="SIGNATURE.SMF"),
- remove=dict(type='bool', default=False),
- ),
- supports_check_mode=True,
- )
- rc, out, err = [0, "", ""]
- params = module.params
- check_mode = module.check_mode
-
- path = params['path']
- dest = params['dest']
- signature = params['signature']
- security_library = params['security_library']
- manifest = params['manifest']
- remove = params['remove']
-
- bin_path = download_SAPCAR(params['binary_path'], module)
-
- if dest is None:
- dest_head_tail = os.path.split(path)
- dest = dest_head_tail[0] + '/'
- else:
- if not os.path.exists(dest):
- os.makedirs(dest, 0o755)
-
- if bin_path is not None:
- command = [module.get_bin_path(bin_path, required=True)]
- else:
- try:
- command = [module.get_bin_path('sapcar', required=True)]
- except Exception as e:
- module.fail_json(msg='Failed to find SAPCAR at the expected path or URL "{0}". Please check whether it is available: {1}'
- .format(bin_path, to_native(e)))
-
- present = check_if_present(command[0], path, dest, signature, manifest, module)
-
- if not present:
- command.extend(['-xvf', path, '-R', dest])
- if security_library:
- command.extend(['-L', security_library])
- if signature:
- command.extend(['-manifest', manifest])
- if not check_mode:
- (rc, out, err) = module.run_command(command, check_rc=True)
- changed = True
- else:
- changed = False
- out = "already unpacked"
-
- if remove:
- os.remove(path)
-
- module.exit_json(changed=changed, message=rc, stdout=out,
- stderr=err, command=' '.join(command))
-
-
-if __name__ == '__main__':
- main()
diff --git a/ansible_collections/community/sap/plugins/modules/system/sap_snote.py b/ansible_collections/community/sap/plugins/modules/system/sap_snote.py
deleted file mode 100644
index 24f393927..000000000
--- a/ansible_collections/community/sap/plugins/modules/system/sap_snote.py
+++ /dev/null
@@ -1,258 +0,0 @@
-#!/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()
diff --git a/ansible_collections/community/sap/plugins/modules/system/sap_system_facts.py b/ansible_collections/community/sap/plugins/modules/system/sap_system_facts.py
deleted file mode 100644
index b5f4eb9b6..000000000
--- a/ansible_collections/community/sap/plugins/modules/system/sap_system_facts.py
+++ /dev/null
@@ -1,206 +0,0 @@
-#!/usr/bin/python
-
-# Copyright: (c) 2022, Rainer Leber rainerleber@gmail.com>
-# 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_system_facts
-
-short_description: Gathers SAP facts in a host
-
-version_added: "1.0.0"
-
-description:
- - This facts module gathers SAP system facts about the running instance.
-
-author:
- - Rainer Leber (@rainerleber)
-
-notes:
- - Supports C(check_mode).
-'''
-
-EXAMPLES = r'''
-- name: Return SAP system ansible_facts
- community.sap.sap_system_fact:
-'''
-
-RETURN = r'''
-# These are examples of possible return values,
-# and in general should use other names for return values.
-ansible_facts:
- description: Facts to add to ansible_facts.
- returned: always
- type: list
- elements: dict
- contains:
- sap:
- description: Facts about the running SAP system.
- type: list
- elements: dict
- returned: When SAP system fact is present
- sample: [
- {
- "InstanceType": "NW",
- "NR": "00",
- "SID": "ABC",
- "TYPE": "ASCS"
- },
- {
- "InstanceType": "NW",
- "NR": "01",
- "SID": "ABC",
- "TYPE": "PAS"
- },
- {
- "InstanceType": "HANA",
- "NR": "02",
- "SID": "HDB",
- "TYPE": "HDB"
- },
- {
- "InstanceType": "NW",
- "NR": "80",
- "SID": "WEB",
- "TYPE": "WebDisp"
- }
- ]
-'''
-
-from ansible.module_utils.basic import AnsibleModule
-import os
-import re
-
-
-def get_all_hana_sid():
- hana_sid = list()
- if os.path.isdir("/hana/shared"):
- # /hana/shared directory exists
- for sid in os.listdir('/hana/shared'):
- if os.path.isdir("/usr/sap/" + sid):
- hana_sid = hana_sid + [sid]
- if hana_sid:
- return hana_sid
-
-
-def get_all_nw_sid():
- nw_sid = list()
- if os.path.isdir("/sapmnt"):
- # /sapmnt directory exists
- for sid in os.listdir('/sapmnt'):
- if os.path.isdir("/usr/sap/" + sid):
- nw_sid = nw_sid + [sid]
- else:
- # Check to see if /sapmnt/SID/sap_bobj exists
- if os.path.isdir("/sapmnt/" + sid + "/sap_bobj"):
- # is a bobj system
- nw_sid = nw_sid + [sid]
- if nw_sid:
- return nw_sid
-
-
-def get_hana_nr(sids, module):
- hana_list = list()
- for sid in sids:
- for instance in os.listdir('/usr/sap/' + sid):
- if 'HDB' in instance:
- instance_nr = instance[-2:]
- # check if instance number exists
- command = [module.get_bin_path('/usr/sap/hostctrl/exe/sapcontrol', required=True)]
- command.extend(['-nr', instance_nr, '-function', 'GetProcessList'])
- check_instance = module.run_command(command, check_rc=False)
- # sapcontrol returns c(0 - 5) exit codes only c(1) is unavailable
- if check_instance[0] != 1:
- hana_list.append({'NR': instance_nr, 'SID': sid, 'TYPE': 'HDB', 'InstanceType': 'HANA'})
- return hana_list
-
-
-def get_nw_nr(sids, module):
- nw_list = list()
- type = ""
- for sid in sids:
- for instance in os.listdir('/usr/sap/' + sid):
- instance_nr = instance[-2:]
- command = [module.get_bin_path('/usr/sap/hostctrl/exe/sapcontrol', required=True)]
- # check if returned instance_nr is a number because sapcontrol returns all if a random string is provided
- if instance_nr.isdigit():
- command.extend(['-nr', instance_nr, '-function', 'GetInstanceProperties'])
- check_instance = module.run_command(command, check_rc=False)
- if check_instance[0] != 1:
- for line in check_instance[1].splitlines():
- if re.search('INSTANCE_NAME', line):
- # convert to list and extract last
- type_raw = (line.strip('][').split(', '))[-1]
- # split instance number
- type = type_raw[:-2]
- nw_list.append({'NR': instance_nr, 'SID': sid, 'TYPE': get_instance_type(type), 'InstanceType': 'NW'})
- return nw_list
-
-
-def get_instance_type(raw_type):
- if raw_type[0] == "D":
- # It's a PAS
- type = "PAS"
- elif raw_type[0] == "A":
- # It's an ASCS
- type = "ASCS"
- elif raw_type[0] == "W":
- # It's a Webdisp
- type = "WebDisp"
- elif raw_type[0] == "J":
- # It's a Java
- type = "Java"
- elif raw_type[0] == "S":
- # It's an SCS
- type = "SCS"
- elif raw_type[0] == "E":
- # It's an ERS
- type = "ERS"
- else:
- # Unknown instance type
- type = "XXX"
- return type
-
-
-def run_module():
- module_args = dict()
- system_result = list()
-
- result = dict(
- changed=False,
- ansible_facts=dict(),
- )
-
- module = AnsibleModule(
- argument_spec=module_args,
- supports_check_mode=True,
- )
-
- hana_sid = get_all_hana_sid()
- if hana_sid:
- system_result = system_result + get_hana_nr(hana_sid, module)
-
- nw_sid = get_all_nw_sid()
- if nw_sid:
- system_result = system_result + get_nw_nr(nw_sid, module)
-
- if system_result:
- result['ansible_facts'] = {'sap': system_result}
- else:
- result['ansible_facts']
-
- if module.check_mode:
- module.exit_json(**result)
-
- module.exit_json(**result)
-
-
-def main():
- run_module()
-
-
-if __name__ == '__main__':
- main()
diff --git a/ansible_collections/community/sap/plugins/modules/system/sap_task_list_execute.py b/ansible_collections/community/sap/plugins/modules/system/sap_task_list_execute.py
deleted file mode 100644
index 0ae25903f..000000000
--- a/ansible_collections/community/sap/plugins/modules/system/sap_task_list_execute.py
+++ /dev/null
@@ -1,340 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-
-# Copyright: (c) 2021, Rainer Leber <rainerleber@gmail.com>
-# 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_task_list_execute
-short_description: Perform SAP Task list execution
-version_added: "0.1.0"
-description:
- - The M(community.sap.sap_task_list_execute) 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.
- - Tasks in the task list which requires manual activities will be confirmed automatically.
- - This module will use the RFC package C(STC_TM_API).
-
-requirements:
- - pyrfc >= 2.4.0
- - xmltodict
-
-options:
- 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.
- default: '00'
- type: str
- client:
- description:
- - The client number to connect to.
- - You must quote the value to ensure retaining the leading zeros.
- default: '000'
- type: str
- task_to_execute:
- description: The task list which will be executed.
- required: true
- type: str
- task_parameters:
- description:
- - The tasks and the parameters for execution.
- - If the task list does not need any parameters, this could be empty.
- - If only specific tasks from the task list should be executed,
- the tasks even when no parameter is needed must be provided
- alongside with the module parameter I(task_skip=true).
- type: list
- elements: dict
- suboptions:
- TASKNAME:
- description: The name of the task in the task list.
- type: str
- required: true
- FIELDNAME:
- description: The name of the field of the task.
- type: str
- VALUE:
- description: The value which have to be set.
- type: raw
- task_settings:
- description:
- - Setting for the execution of the task list. This can be the following as in TCODE SE80 described.
- Check Mode C(CHECKRUN), Background Processing Active C(BATCH) (this is the default value),
- Asynchronous Execution C(ASYNC), Trace Mode C(TRACE), Server Name C(BATCH_TARGET).
- default: ['BATCH']
- type: list
- elements: str
- task_skip:
- description:
- - If this parameter is C(true), not defined tasks in I(task_parameters) are skipped.
- - This could be the case when only certain tasks should run from the task list.
- default: false
- type: bool
-
-notes:
- - Does not support C(check_mode). Always returns that the state has changed.
-author:
- - Rainer Leber (@rainerleber)
-'''
-
-EXAMPLES = r'''
-# Pass in a message
-- name: Test task execution
- community.sap.sap_task_list_execute:
- conn_username: DDIC
- conn_password: Passwd1234
- host: 10.1.8.10
- sysnr: '01'
- client: '000'
- task_to_execute: SAP_BASIS_SSL_CHECK
- task_settings: batch
-
-- name: Pass in input parameters
- community.sap.sap_task_list_execute:
- conn_username: DDIC
- conn_password: Passwd1234
- host: 10.1.8.10
- sysnr: '00'
- client: '000'
- task_to_execute: SAP_BASIS_SSL_CHECK
- task_parameters :
- - { 'TASKNAME': 'CL_STCT_CHECK_SEC_CRYPTO', 'FIELDNAME': 'P_OPT2', 'VALUE': 'X' }
- - TASKNAME: CL_STCT_CHECK_SEC_CRYPTO
- FIELDNAME: P_OPT3
- VALUE: X
- task_settings: batch
-
-# Exported environment variables
-- name: Hint if module will fail with error message like ImportError libsapnwrfc.so...
- community.sap.sap_task_list_execute:
- conn_username: DDIC
- conn_password: Passwd1234
- host: 10.1.8.10
- sysnr: '00'
- client: '000'
- task_to_execute: SAP_BASIS_SSL_CHECK
- task_settings: batch
- environment:
- SAPNWRFC_HOME: /usr/local/sap/nwrfcsdk
- LD_LIBRARY_PATH: /usr/local/sap/nwrfcsdk/lib
-'''
-
-RETURN = r'''
-msg:
- description: A small execution description.
- type: str
- returned: always
- sample: 'Successful'
-out:
- description: A complete description of the executed tasks. If this is available.
- type: list
- elements: dict
- returned: on success
- sample: [...,{
- "LOG": {
- "STCTM_S_LOG": [
- {
- "ACTIVITY": "U_CONFIG",
- "ACTIVITY_DESCR": "Configuration changed",
- "DETAILS": null,
- "EXEC_ID": "20210728184903.815739",
- "FIELD": null,
- "ID": "STC_TASK",
- "LOG_MSG_NO": "000000",
- "LOG_NO": null,
- "MESSAGE": "For radiobutton group ICM too many options are set; choose only one option",
- "MESSAGE_V1": "ICM",
- "MESSAGE_V2": null,
- "MESSAGE_V3": null,
- "MESSAGE_V4": null,
- "NUMBER": "048",
- "PARAMETER": null,
- "PERIOD": "M",
- "PERIOD_DESCR": "Maintenance",
- "ROW": "0",
- "SRC_LINE": "170",
- "SRC_OBJECT": "CL_STCTM_REPORT_UI IF_STCTM_UI_TASK~SET_PARAMETERS",
- "SYSTEM": null,
- "TIMESTMP": "20210728184903",
- "TSTPNM": "DDIC",
- "TYPE": "E"
- },...
- ]}}]
-'''
-
-from ansible.module_utils.basic import AnsibleModule, missing_required_lib
-import traceback
-try:
- from pyrfc import Connection
-except ImportError:
- HAS_PYRFC_LIBRARY = False
- PYRFC_LIBRARY_IMPORT_ERROR = traceback.format_exc()
-else:
- HAS_PYRFC_LIBRARY = True
-try:
- import xmltodict
-except ImportError:
- HAS_XMLTODICT_LIBRARY = False
- XMLTODICT_LIBRARY_IMPORT_ERROR = traceback.format_exc()
-else:
- HAS_XMLTODICT_LIBRARY = True
-
-
-def call_rfc_method(connection, method_name, kwargs):
- # PyRFC call function
- return connection.call(method_name, **kwargs)
-
-
-def process_exec_settings(task_settings):
- # processes task settings to objects
- exec_settings = {}
- for settings in task_settings:
- temp_dict = {settings.upper(): 'X'}
- for key, value in temp_dict.items():
- exec_settings[key] = value
- return exec_settings
-
-
-def xml_to_dict(xml_raw):
- try:
- xml_parsed = xmltodict.parse(xml_raw, dict_constructor=dict)
- xml_dict = xml_parsed['asx:abap']['asx:values']['SESSION']['TASKLIST']
- except KeyError:
- xml_dict = "No logs available."
- return xml_dict
-
-
-def run_module():
-
- params_spec = dict(
- TASKNAME=dict(type='str', required=True),
- FIELDNAME=dict(type='str'),
- VALUE=dict(type='raw'),
- )
-
- # define available arguments/parameters a user can pass to the module
- module = AnsibleModule(
- argument_spec=dict(
- # values for connection
- 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="00"),
- client=dict(type='str', default="000"),
- # values for execution tasks
- task_to_execute=dict(type='str', required=True),
- task_parameters=dict(type='list', elements='dict', options=params_spec),
- task_settings=dict(type='list', elements='str', default=['BATCH']),
- task_skip=dict(type='bool', default=False),
- ),
- supports_check_mode=False,
- )
- result = dict(changed=False, msg='', out={})
-
- params = module.params
-
- username = params['conn_username'].upper()
- password = params['conn_password']
- host = params['host']
- sysnr = params['sysnr']
- client = params['client']
-
- task_parameters = params['task_parameters']
- task_to_execute = params['task_to_execute']
- task_settings = params['task_settings']
- task_skip = params['task_skip']
-
- if not HAS_PYRFC_LIBRARY:
- module.fail_json(
- msg=missing_required_lib('pyrfc'),
- exception=PYRFC_LIBRARY_IMPORT_ERROR)
-
- if not HAS_XMLTODICT_LIBRARY:
- module.fail_json(
- msg=missing_required_lib('xmltodict'),
- exception=XMLTODICT_LIBRARY_IMPORT_ERROR)
-
- # basic RFC connection with pyrfc
- try:
- conn = Connection(user=username, passwd=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)
-
- try:
- raw_params = call_rfc_method(conn, 'STC_TM_SCENARIO_GET_PARAMETERS',
- {'I_SCENARIO_ID': task_to_execute})
- except Exception as err:
- result['error'] = str(err)
- result['msg'] = 'The task list does not exist.'
- module.fail_json(**result)
- exec_settings = process_exec_settings(task_settings)
- # initialize session task
- session_init = call_rfc_method(conn, 'STC_TM_SESSION_BEGIN',
- {'I_SCENARIO_ID': task_to_execute,
- 'I_INIT_ONLY': 'X'})
- # Confirm Tasks which requires manual activities from Task List Run
- for task in raw_params['ET_PARAMETER']:
- call_rfc_method(conn, 'STC_TM_TASK_CONFIRM',
- {'I_SESSION_ID': session_init['E_SESSION_ID'],
- 'I_TASKNAME': task['TASKNAME']})
- if task_skip:
- for task in raw_params['ET_PARAMETER']:
- call_rfc_method(conn, 'STC_TM_TASK_SKIP',
- {'I_SESSION_ID': session_init['E_SESSION_ID'],
- 'I_TASKNAME': task['TASKNAME'], 'I_SKIP_DEP_TASKS': 'X'})
- # unskip defined tasks and set parameters
- if task_parameters is not None:
- for task in task_parameters:
- call_rfc_method(conn, 'STC_TM_TASK_UNSKIP',
- {'I_SESSION_ID': session_init['E_SESSION_ID'],
- 'I_TASKNAME': task['TASKNAME'], 'I_UNSKIP_DEP_TASKS': 'X'})
-
- call_rfc_method(conn, 'STC_TM_SESSION_SET_PARAMETERS',
- {'I_SESSION_ID': session_init['E_SESSION_ID'],
- 'IT_PARAMETER': task_parameters})
- # start the task
- try:
- session_start = call_rfc_method(conn, 'STC_TM_SESSION_RESUME',
- {'I_SESSION_ID': session_init['E_SESSION_ID'],
- 'IS_EXEC_SETTINGS': exec_settings})
- except Exception as err:
- result['error'] = str(err)
- result['msg'] = 'Something went wrong. See error.'
- module.fail_json(**result)
- # get task logs because the execution may successfully but the tasks shows errors or warnings
- # returned value is ABAPXML https://help.sap.com/doc/abapdocu_755_index_htm/7.55/en-US/abenabap_xslt_asxml_general.htm
- session_log = call_rfc_method(conn, 'STC_TM_SESSION_GET_LOG',
- {'I_SESSION_ID': session_init['E_SESSION_ID']})
-
- task_list = xml_to_dict(session_log['E_LOG'])
-
- result['changed'] = True
- result['msg'] = session_start['E_STATUS_DESCR']
- result['out'] = task_list
-
- module.exit_json(**result)
-
-
-def main():
- run_module()
-
-
-if __name__ == '__main__':
- main()