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: 
quovadis
Product and Topic Expert
Product and Topic Expert























As depicted below, a kubernetes API server is at the heart of any kyma/k8s cluster.

The API server exposes an HTTP API for pretty much every single k8s cluster object

Whether using kubectl command line interface or a kubernetes client library, the communication is passing through the kubernetes API server

Putting it all together


With kubernetes environments, a yaml formatted textual description of the desired state (a contract) is translated into a sequence of HTTP API calls as to fulfil the agreed contractual obligation....















Any Kyma/k8s API server can output the current APIs definitions via the /openapi/v2 endpoint.

That's pretty convenient as the swagger OpenAPI specification will only contain the API definitions supported by this very cluster's kubernetes version.

Step 1. Download the k8s cluster API definition to a local file. The API definition is in OpenAPI/Swagger 2.0 format. It can be used "as is".

a. You may download the swagger definition of your k8s cluster APIs into a local json file, as follows:
$ curl -k --header "Authorization: Bearer <token>" https://api.<cluster ID>.kyma.shoot.live.k8s-hana.ondemand.com/openapi/v2 > <cluster ID>-swagger.json

Please note, a bearer access token (for instance from a ServiceAccount) is required in the Authorization header

b. or, you may first kubelogin to your k8s cluster and then use kubectl to download the swagger api definition, as follows:
kubectl get --raw /openapi/v2  --kubeconfig ~/.kube/kubeconfig--shoot--kyma--<cluster ID>.yaml > <cluster ID>-swagger.json

c. or, you may open a reverse proxy to your cluster api server:
$ kubectl proxy --port=8080 --kubeconfig ~/.kube/kubeconfig--shoot--kyma--<cluster ID>.yaml
Starting to serve on 127.0.0.1:8080

Then you an either download the APIs spec into a local file
$ curl http://localhost:8080/openapi/v2 > <cluster ID>-swagger.json

or start browsing the APIs locally, for instance:
http://localhost:8080/version
{
"major": "1",
"minor": "25",
"gitVersion": "v1.25.6",
"gitCommit": "ff2c119726cc1f8926fb0585c74b25921e866a28",
"gitTreeState": "clean",
"buildDate": "2023-01-18T19:15:26Z",
"goVersion": "go1.19.5",
"compiler": "gc",
"platform": "linux/amd64"
}

Last but not least, you could also use a docker hosted UI to run your APIs as follows:
$ docker run --rm -p 80:8080 -e BASE_URL=/swagger -e SWAGGER_JSON=/<cluster ID>-swagger.json -v $(pwd)/<cluster ID>-swagger.json:/<cluster ID>-swagger.json swaggerapi/swagger-ui

SAP API Management proxies


However, most likely the local access to the api server APIs is not of much use. Thus, let's see how to leverage SAP API Management to create an internet API proxy to the api server endpoint.

Step 1. Convert downloaded OpenAPI/Swagger spec to OpenAPI 3.0 format.

I have used a docker based OpenAPI/Swagger 2.0 to OpenAPI 3.0 Converter, as follows:
$ docker pull swaggerapi/swagger-converter
Using default tag: latest
latest: Pulling from swaggerapi/swagger-converter
Digest: sha256:a4f05c2df58d4168019fe28ef3fc9d6494e077e2fd1f8d714cd8501e41a0ed6e
Status: Image is up to date for swaggerapi/swagger-converter:latest
docker.io/swaggerapi/swagger-converter:latest

$ docker run -d -p 8080:8080 --name swagger-converter swaggerapi/swagger-converter

A hint: Use the POST asynchronous method for the conversion and select the output format as yaml.

Step 2a. Upload the OpenAPI 3.x file into SAP API Management.

Use any text editor to replace the header of the above generated yaml file with the header depicted below, where x-targetEndpoint is the kyma cluster api server endpoint URL and servers.url is the API proxy URL.
openapi: 3.0.1
info:
title: api.123456.kyma.ondemand.com
x-targetEndpoint: 'https://api.123456.kyma.ondemand.com'
version: 1.0.0
servers:
- url: >-
https://<BTP zoneid>-trial.integrationsuitetrial-apim.eu10.hana.ondemand.com:443/k8s-123456
paths: {}

Good to know:

  • The generated yaml file is quite large. After some trial and error, I ended up using FireFox browser to apply the yaml definition in the API Management API editor.


Step 2b. Implement a security policy using the embedded policy editor


You will need to assign the sapapim.accessToken variable with the value of the bearer access token coming from your kyma cluster, for instance:
context.setVariable("sapapim.accessToken" , bearer_kyma_default);

<!-- This policy can be used to create or modify the standard HTTP request and response messages -->
<AssignMessage async="false" continueOnError="false" enabled="true" xmlns='http://www.sap.com/apimgmt'>
<Set>
<Headers>
<Header name="Accept-Encoding">gzip,deflate</Header>
<Header name="Content-Type">application/json</Header>
<Header name="Accept">application/json</Header>
<Header name="Authorization">Bearer {sapapim.accessToken}</Header>
</Headers>
</Set>
<IgnoreUnresolvedVariables>false</IgnoreUnresolvedVariables>
<AssignTo createNew="false" type="request">request</AssignTo>
</AssignMessage>

Step 2c. After updating the policy, save and deploy the API proxy.

Next steps


You can also add the built-in CORS management policy if you fancy using the API server proxy with for instance SAP Build Apps or other HTML5 application builder...


Do not forget to add the Authorization header to both handleoptions (PreFlow) and setCORS (PostFlow) policies on the proxy endpoint.
<AssignMessage async="false" continueOnError="false" enabled="true" xmlns='http://www.sap.com/apimgmt'>
<Add>
<Headers>
<Header name="Access-Control-Allow-Origin">*</Header>
<Header name="Access-Control-Allow-Headers">set-cookie, origin, accept, maxdataserviceversion, x-csrf-token, apikey, dataserviceversion, accept-language, x-http-method,content-type,X-Requested-With, Authorization</Header>
<Header name="Access-Control-Max-Age">3628800</Header>
<Header name="Access-Control-Allow-Methods">GET, PUT, POST, DELETE</Header>
<Header name="Access-Control-Expose-Headers">set-cookie, x-csrf-token, x-http-method</Header>

</Headers>
</Add>
<IgnoreUnresolvedVariables>false</IgnoreUnresolvedVariables>
<AssignTo createNew="false" type="response">response</AssignTo>
</AssignMessage>

That should not take more than 5 minutes.

After policy update, proxy save and then deploy you will get a CORS compliant API proxy:


 

Conclusion


Last but not least, I hope you have enjoyed reading this blog post. Feel free to provide feedback in the comments section below.

If you have further questions around Kyma and security topics in particular, feel free to post them in the comments area of this blog or in the SAP Community.

 




Additional information








Pre-requisistes:

  • cluster-admin access to SAP BTP, Kyma Runtime k8s cluster

  • SAP API Management access


Other resources:






SAP Kyma Community and SAP BTP, Kyma runtime Q&A Tags

Follow me in SAP Community: piotr.tesny