Technology Blogs by SAP
Learn how to extend and personalize SAP applications. Follow the SAP technology blog for insights into SAP BTP, ABAP, SAP Analytics Cloud, SAP HANA, and more.
cancel
Showing results for 
Search instead for 
Did you mean: 
naeem_maqsud
Advisor
Advisor
Update Dec. 2022: SAP Landscape Management (LaMa) SP25 added REST API (outgoing) provider that can also be used for the examples covered below. Refer to this blog for details.

Introduction

In a previous blog, I covered the REST API interface of SAP Landscape Management (LaMa). This interface allows actions to be performed by LaMa with API calls coming in from other applications or your own scripts. Refer to Figure 1.


Figure 1: Incoming REST API Calls

In this blog I'm going to cover the reverse scenario where API or other execution calls are made from LaMa to external applications. Refer to Figure 2.

Making external calls from LaMa may be needed when creating a custom operation/process that requires triggering an action in an external application. Some examples could be kicking off a backup using a 3rd party tool, creating service requests in a ticketing system, triggering an event in an external system, launching external automation tools/scripts (e.g. ansible, chef) etc.

The supported provider implementation definitions in LaMa are (table updated to add provider type REST after the SP25 release):































Type Description
SAP host agent registered scripts A script that is registered on and executed by SAP Host Agent.
HTTP post service A servlet or similar that is called directly by SAP Landscape Management.
REST (as of SP25) REST API calls made directly from SAP Landscape Management (LaMa)
Web service A web service (server-side) that implements the WSDL defined by SAP Landscape Management (LaMa).
Remote function call An ABAP function module that is called and executed by SAP Landscape Management.
Confirmation action A text that appears for user confirmation.

Covering all the use cases mentioned above is not in scope of this blog, but I will give some basic examples to demonstrate the capability. I will use GitHub API in example 1 and Ansible in example 2.

We will use Automation Studio in SAP Landscape Management to get this done.

Since we need to make a REST API call, we are going to create a custom process that leverages "Script Registered with Host Agent" to make the necessary calls. It may be possible to use the HTTP post service but we will use the scripts approach in this blog.

In this case you have to decide which managed host you will use for such external calls. You would designate this server as a LaMa proxy or trusted host allowed to make such calls to external interfaces.

 


Figure 2: Outgoing calls

Disclaimer

This blog is published “AS IS”. Any software coding and/or code lines / strings (“Code”) included are only examples and are not intended to be used in any productive system environment. The Code is only intended to better explain and visualize the features of the SAP Landscape Management Automation Studio. No effort has been made to make the code production quality (e.g. security, error handling, robustness, etc). If you use any of the code shown, you are doing it at your own risk.

Information in this blog could include technical inaccuracies or typographical errors. Changes may be periodically made.

Assumptions

It is assumed that your environment is already setup correctly for creating custom processes in LaMa. This blog does not go over all the configuration steps. If this is your first time using LaMa Automation Studio then I recommend that you start with something simple. Please refer to this blog for other examples. All examples below use an environment with LaMa Enterprise Edition 3.0 SP13, SuSE Linux Enterprise 12 SP2 (all hosts).

Example 1: Outgoing API calls to GitHub

In this section we will create and update Gists on GitHub. A Gist is a mechanism to share snippets or excerpts of data with others. It can be a string of code, a script or some other small piece of data.

We will use access tokens as authentication mechanism. We will make the API calls from a script using the "curl" command. First we will test the commands individually and then put in a script to be called by LaMa.

Step 1 is to create the access token on GitHub. Creation of access tokens is via the web interface that GitHub offers. You access it by clicking the settings icon.


Give the token a meaningful name and define the scope. You can also revoke this token at a later time. After you generate the token, copy and paste it somewhere as this will be the only time you will see it.

Let's now make sure the token works.
curl -u "<github_username>:<token>" https://api.github.com/user

You should get an output similar to this:

{
"login": "xyz",
"id": 63888981,
"node_id": "xyz",
"avatar_url": "https://avatars2.githubusercontent.com/u/63888981?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/xyz",
"html_url": "https://github.com/xyz",
"followers_url": "https://api.github.com/users/xyz/followers",
"following_url": "https://api.github.com/users/xyz/following{/other_user}",
"gists_url": "https://api.github.com/users/xyz/gists{/gist_id}",
"starred_url": "https://api.github.com/users/xyz/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/xyz/subscriptions",
"organizations_url": "https://api.github.com/users/xyz/orgs",
"repos_url": "https://api.github.com/users/xyz/repos",
"events_url": "https://api.github.com/users/xyz/events{/privacy}",
"received_events_url": "https://api.github.com/users/xyz/received_events",


Now lets create a new Gist called "LaMa_gist_1.txt" which will have initial text of "LaMa Demo of Gist Create" and description of "Created via API"
curl -u "<username>:<token>" -X POST --data '{"description":"Created via API","public":"true","files":{"LaMa_gist_1.txt":{"content":"LaMa Demo of Gist Create"}}' https://api.github.com/gists

In the output you will get a lot of text and in the beginning is the full URL of the newly created Gist file as well as the ID.  See bold text below from the sample output. Note this ID down as we will need it to perform an update.

"{
"url": "https://api.github.com/gists/db02193dc5335f8fbb773210b260166e",
"forks_url": "https://api.github.com/gists/db02193dc5335f8fbb773210b260166e/forks",
"commits_url": "https://api.github.com/gists/db02193dc5335f8fbb773210b260166e/commits",
"id": "db02193dc5335f8fbb773210b260166e",
"node_id": "MDQ6R2lzdGRiMDIxOTNkYzUzMzVmOGZiYjc3MzIxMGIyNjAxNjZl",
"git_pull_url": "https://gist.github.com/db02193dc5335f8fbb773210b260166e.git",
"git_push_url": "https://gist.github.com/db02193dc5335f8fbb773210b260166e.git",
"html_url": "https://gist.github.com/db02193dc5335f8fbb773210b260166e",
"files": {


 

Now login to the web portal of GitHub and view your Gists. You should see this new Gist.


 

Now let's update the above Gist with additional text "LaMa Demo Gist Updated via API".
curl -u "<username>:<token>" -X PATCH --data '{"description":"Updated via API","public":"true","files":{"LaMa_gist_1.txt":{"content":"LaMa Demo Gist Updated via API"}}' https://api.github.com/gists/db02193dc5335f8fbb773210b260166e

 

On GitHub web you should see the update:


 

Now that we know the command line works, let's create a custom operation that does a Gist create and an update.

Create the configuration files in directory /usr/sap/hostctrl/exe/operations.d on the managed host that is going to run the commands.

Create file gist_create.conf
Username: root
Name: gist_create
Description: Create gist on GitHub
Command: /usr/sap/scripts/gist_create.sh $[PARAM-GITUSER:#required] $[PARAM-TOKEN:#required] $[PARAM-FILENAME:#required] $[PARAM-TEXT:#required]
ResultConverter: flat
Platform: Unix

 

Set permissions:
chown root:root <.conf file>
chmod 755 <.conf file>

 

Create the bash script in a directory of your choice (in my case it was in /usr/sap/scripts):

Script name: "gist_create.sh".



#!/bin/bash
GISTUSER=$1
TOKEN=$2
FILENAME=$3
TEXT=$4
COMMAND="curl -u \"$GISTUSER:$TOKEN\" -X POST --data '{\"description\":\"Created via API\",\"public\":\"true\",\"files\":{\"$FILENAME\":{\"content\":\"$TEXT\"}}' https://api.github.com/gists"
eval $COMMAND

 

Set permissions
chown root:root gist_create.sh

chmod 755 gist_create.sh

 

Create file gist_update.conf
Username: root
Name: gist_update
Description: Update gist on GitHub
Command: /usr/sap/scripts/gist_update.sh $[PARAM-GITUSER:#required] $[PARAM-TOKEN:#required] $[PARAM-FILENAME:#required] $[PARAM-TEXT:#required] $[PARAM-GISTID:#required]
ResultConverter: flat
Platform: Unix

 

Set permissions:
chown root:root <.conf file>
chmod 755 <.conf file>

 

Create the bash script in a directory of your choice (in my case it was in /usr/sap/scripts):

Script name: "gist_update.sh"



#!/bin/bash
GISTUSER=$1
TOKEN=$2
FILENAME=$3
TEXT=$4
GISTID=$5
COMMAND="curl -u \"$GISTUSER:$TOKEN\" -X POST --data '{\"description\":\"Updated
via API\",\"public\":\"true\",\"files\":{\"$FILENAME\":{\"content\":\"$TEXT\"}}
' https://api.github.com/gists/$GISTID"
eval $COMMAND

 

Set permissions
chown root:root gist_update.sh

chmod 755 gist_update.sh

 

Provider Definition for Gist Create

Login to LaMa and create a new provider definition as “Script Registered with Host Agent”



Add host (designated as your proxy) from the drop down and click “Retrieve Scripts”. The host agent fills the drop list.

Select the "Host Name" and click "Retrieve Scripts". Choose the script (the configuration file) “gist_create” and give Name of “gist_create”. Check mark "Execute on Central Host Only" and fill in the trusted host information. Click on Create Provider.


Click on the newly created provider definition.


 

Go to Parameters tab and click on "Add Parameter". Add the below 4 parameters of Type string and make Mandatory yes. Also mark the parameter TOKEN as secure.

 


 

Custom Operation for Gist Create

Go to Automation Studio -> Custom Operation -> Create


 

Now test the newly created custom operation. Go to Operations -> Hosts

Run the custom operation in the Operations Group API (against any host). Execution will only occur on the central host defined earlier when creating the provider definition.


Fill in the parameters


 

Click Execute

Verify that the gist was created on the GitHub web site.

If successful then get the ID of the gist from the LaMa Monitor. Go to Monitoring -> Activities and for the above operation look for the ID.


 

Note this down so we can do an update to this after creating the custom operation for an update.

Follow the same steps above to:

  • Create the provider definition gist_update from the registered script gist_update (using gist_update.conf and gist_update.sh files)

  • Create the new custom operation "API_GIST_UPDATE" from the new provider definition

    • There is 1 extra parameter - GISTID (to provide the ID of the gist we are updating)





Now test the update.


After execution you should now see the Gist updated on the GitHub site with the new text.


Example 2: Outgoing calls to Ansible

In this example we assume that Ansible is already installed and configured on the trusted system and is able to perform automation tasks against other hosts. In my test the username "ansible" has been created on the trusted host as well as the hosts on which we want to perform automation tasks. Username "ansible" is able to ssh from trusted host to the other hosts without being prompted for password (i.e. using certificates).

Using Example 1 as a reference (which has a bit more detail), perform the following steps.

  • Check your ansible inventory in /etc/ansible/hosts. The hosts listed here are the ones that will be updated by ansible with the 'all' option we are using in this test


 

  • Create the file ansible_test.conf in /usr/sap/hostctrl/exe/operations.d


Name: ansible_test
Username: ansible
Description: Run ansible commands
Command: /usr/sap/scripts/ansible_test.sh
ResultConverter: flat
Platform: Unix

 

  • Create the file /usr/sap/scripts/ansible_test.sh


#!/bin/sh
. /opt/ansible/ansible/hacking/env-setup -q
/opt/ansible/ansible/bin/ansible all -m command -a 'uname -r' -o
/opt/ansible/ansible/bin/ansible all -m copy -a 'content="Managed by Ansible\n" dest=/tmp/motd'

 

  • Change permissions on both files


chown root:root <file>
chmod 755 <file>

 

  • Create Provider Definition



 

  • Create Custom Operation using above provider definition




 

  • Perform the custom operation



 

  • Monitor the progress in Monitoring -> Activities


 

  • When successfully completed you should see that the file /tmp/motd has been updated on all the hosts that are setup for automation with ansible.


 

You have now learnt to make simple outgoing API calls as well as triggering Ansible from LaMa.

For more information on Automation Studio please refer to:

  1. https://blogs.sap.com/2020/02/28/sap-landscape-management-lama-automation-studio/

  2. SAP Landscape Management Enterprise 3.0 User Guide

2 Comments