oke-cluster-start-stop, a kubectl Plugin for starting/stopping all the Compute Nodes of an OKE Cluster

If you want to start or stop all of your OKE data plane cluster nodes you must go to all the nodes and execute the action one by one.

The current post depicts a kubectl plugin extension created for helping you to start/stop your oke clusters.

NOTES: The tool has been developed and tested in Mac. In addition the tool utilises jq which is installed automatically in case it is not.

Take a look at this github page for instructions and code. Here an example of the tool at work:

NOTE: The tool is gonna be submitted soon for approval in the krew-index (like a package manager for kubectl plugins), meanwhile you can install it locally as follows:

git clone https://github.com/javiermugueta/oke-cluster-start-stop.git
cd oke-cluster-start-stop
kubectl krew install --manifest=oke-cluster-start-stop.yaml --archive=oke-cluster-start-stop-1.0.0.zip

In addition you can execute the tool as a stand alone script as well.

Hope it helps! 🙂


Kubectl plugins developer guide

Oracle SaaS | Analysing the Structure and Morphology of the REST API Methods

Oracle SaaS API’s have a structure that is equal for all the “business entities” across the different modules (Finance, Loyalty, Supply Chain, …) such as invoices, expenses, loyalty transactions and so on. Let’s analyze the pattern. In this episode, we are focusing on the “Get all xxx” methods because it conforms a pattern that we’ll utilise in a sooner construct which we are working on for building a tool that extracts and publishes changes in the data in near-realtime.


Verb for all of them is obviously GET


Endpoint is <fqdnurl>/<endpoint> where

<fqdn> is the server url such as https://iiii-eeee.fa.em2.oraclecloud.com
<endpoint> is the API endpoint provided in the documentation such as /fscmRestApi/resources/ 

Data Retrieved

If you execute the API call and data exists, conditions are valid and the user you are using for the connection has privileges to read, a JSON structure is retrieved up to the number of records in the limit parameter (default 25). If more records exist it is notified in the hasMore field in the response.


expand: Includes child records of the entity, you can specify which childs to include or all for example ?expand=invoiceLines (tip: if onlyData is false (default) the links provide you the name of the child entities)
fields: If you don't want all the fields in the response, include the names of the fields expected
limit: maximum number of records per call execution
offset: the ordinal number of the set of records retrieved according to the total and the limit parameter. For example if limit is 5 and you want the records from 6 to 10, offset must be set to 1
onlyData: by default, response JSON includes child objects links, putting this value to false disables that option
orderBy: fields and order criteria for retrieving data such as ?orderBy=InvoiceId:asc,SupplierSite:desc
q: the filter condition to get data such as ?q=InvoiceAmount>1000
totalResults: by default is false so total records retrieved are not evaluated, if true they are counted with the drawback of a more computation cost and probably lower response time and performance
totalResults effect
Get all banks REST API
Get all expense records API
Get all invoices API


In the following example we are requesting invoices and their lines with an amount greater than 1000 indicating that we want to know the number of invoices that accomplish the criteria

curl -X GET -k -H 'Content-Type: application/vnd.oracle.adf.resourceitem+json' -u jxvxxr.mxgxxtx@xrxclx.cxm:password "https:/iiii-eee.fa.em2.oraclecloud.com//fscmRestApi/resources/>1000&expand=invoiceLines&onlyData=true"


  "items" : [ {
    "InvoiceId" : 1,
    "InvoiceNumber" : "DFS03",
    "InvoiceCurrency" : "EUR",
    "PaymentCurrency" : "EUR",
    "InvoiceAmount" : 1100,
    "CreationDate" : "2019-07-10T08:33:13+00:00",
    "CreatedBy" : "dxnx.fxrnxndxz@xrxclx.cxm",
    "LastUpdatedBy" : "dxnx.fxrnxndxz@xrxclx.cxm",
    "LastUpdateDate" : "2019-07-16T12:46:37+00:00",
    "LastUpdateLogin" : "8AC9D26BC392042BE053A46F660ACD78",
    "invoiceLines" : [ {
      "LineNumber" : 1,
      "LineAmount" : 1000,
      "AccountingDate" : "2019-07-10",
      "MultiperiodAccountingAccrualAccount" : "",
      "CreatedBy" : "dxnx.fxrnxndxz@xrxclx.cxm",
      "CreationDate" : "2019-07-10T08:33:18+00:00",
      "LastUpdateDate" : "2019-07-10T08:34:56+00:00",
      "LastUpdatedBy" : "dxnx.fxrnxndxz@xrxclx.cxm",
      "LastUpdateLogin" : "8AC9F283AC3E043EE053A46F660A9D93"
    }, {
      "LineNumber" : 2,
      "LineAmount" : 100,
      "AccountingDate" : "2019-07-10",
    } ]
  }, {
    "InvoiceId" : 1001,
    "invoiceLines" : [ {
      "LineNumber" : 1,
      "LineAmount" : 1000,
    }, {
      "LineNumber" : 2,
      "LineAmount" : 100,
    } ]
  }, …
    } ]
  } ],
  "totalResults" : 155,
  "count" : 5,
  "hasMore" : true,
  "limit" : 5,
  "offset" : 0,
  "links" : [ {

So far, so good! Please note we have highlighted CreationDate and LastUpdateDate in the records, w’ll se the reason in a new post sooner, stay tuned!

So that’s all folks for now, hope it helps! 🙂

More Info

Oracle Cloud Applications Documentation Index

REST API for Finiancials

REST API for Supply Chain & Manufacturing

And so on… locate the REST API on the left panel of the documentation for each module listed in the index

Set Up an Ingress Controller in OKE Cluster

Here a recipe to create a ingresscontroller.

Step 1: setting up the nginx ingress controller

kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/static/mandatory.yaml

Step 2: exposing the ingress as a service of type LoadBalancer (as a public IP)

kubectl apply -f https://raw.githubusercontent.com/javiermugueta/rawcontent/master/cloud-generic.yaml

Step 3: Execute this command several times until the external-ip appears as non <pending>, grab the IP for later testing

kubectl get svc -n ingress-nginx

Step 4: a certificate for ssl termination

openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout tls.key -out tls.crt -subj "/CN=nginxsvc/O=nginxsvc"

kubectl create secret tls tls-secret --key tls.key --cert tls.crtopenssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout tls.key -out tls.crt -subj "/CN=nginxsvc/O=nginxsvc"

Step 5

kubectl create -f https://raw.githubusercontent.com/javiermugueta/rawcontent/master/hello-world-ingress.yaml

Step 6: A typical hello world deployment with a pod in it and 3 replicas

kubectl create -f https://raw.githubusercontent.com/javiermugueta/rawcontent/master/ingress.yaml

Step 7: Test the url and see what happens…

That’s all folks! Hope it helps 🙂

Deploying a Coherence Cluster in Kubernetes

Coherence-Operator is a Kubernetes opeartor for deploying Oracle Coherence in k8s. Let’s see how to do it.

1 Clean previous setup intents:

helm del --purge sample-coherence
helm del --purge sample-coherence-operator
kubectl delete namespace sample-coherence-ns

2 Execute the following:

kubectl config set-context $(kubectl config current-context) --namespace=sample-coherence-ns

helm repo add coherence https://oracle.github.io/coherence-operator/charts

helm repo update

helm --debug install coherence/coherence-operator --name sample-coherence-operator --set "targetNamespaces={}" --set imagePullSecrets=sample-coherence-secret

helm ls

helm status sample-coherence-operator

3 Create a secret with your credentials to Oracle Container Registry:

kubectl create secret docker-registry oracle-container-registry-secret --docker-server=container-registry.oracle.com --docker-username='youruser' --docker-password='yourpasswd' --docker-email='youremail'

4 Install:

helm --debug install coherence/coherence --name sample-coherence --set imagePullSecrets=oracle-container-registry-secret

5 Proxy to a pod:

export POD_NAME=$(kubectl get pods --namespace sample-coherence-ns -l "app=coherence,release=sample-coherence,component=coherencePod" -o jsonpath="{.items[0].metadata.name}")

kubectl --namespace sample-coherence-ns port-forward $POD_NAME 20000:20000

6 Download and install Coherence Stand Alone

7 Download this and this

8 Build the client:

export COHERENCE_HOME=~/Oracle/Middleware/Oracle_Home/coherence
javac -cp .:${COHERENCE_HOME}/lib/coherence.jar HelloCoherence.javaexport COHERENCE_HOME=~/Oracle/Middleware/Oracle_Home/coherence

9 Test it:

java -cp .:${COHERENCE_HOME}/lib/coherence.jar -Dcoherence.cacheconfig=$PWD/example-client-config.xml HelloCoherence

2019-07-11 01:21:33.575/0.538 Oracle Coh...


Oracle Coherence Version Build 68243

2019-07-11 01:21:34.430/1.392 Oracle 

The value of the key is 7

That’s all, hope it helps 🙂

Oracle SaaS Stories | Customisation Framework: Invoking a Service when an Entity is Created/Updated

In this episode we are explaining one of the many mechanisms for executing actions when changes happen in the Cloud App Environment.

In this particular case, as an example, we are calling an external REST service hosted in a kubernetes cluster, that implements a counter. Every time we create or modify a Contact, the external service is called.

Hands on!

Enter in the environment with a user with al least ORA_ASM_APPLICATION_IMPLEMENTATION_CONSULTANT_JOB

Go to “Manage Sandboxes”:

Create a new sandbox and set active:

Go to Application Composer:

Click on “Common Setup-Web Services”:

Create a new Web Service:

Select REST/SOAP appropriately:

Put the information of your service endpoint:

Search for the “Contact” business object, click on “Server Scripts”, then “triggers”, then click on “create”:

Crate a trigger of type “After Create”:

Go to the Web Services tab on the right pane, locate the service you want to invoke and click on “insert”:

The code invoked when a new contact is created is put in the editor. Save it.

NOTE: You can create another trigger for other events, such as “AfterTransactionPosted”, etc.

Let’s test it!

Check the status of the external web service:

Go to the Contacts Menu:

Create a new contact, for example Abelardo Pirindiki:

Check the status of the external service and see it has been called:

And that’s all folks, hope it helps! 🙂

Oracle SaaS Stories | Exporting Data to Cloud Object Storage with BI Cloud Extract Tool

Business Intelligence Cloud Extract is a tool that you can use to export data from Oracle SaaS. The tool is under /biacm service url, such as https://xxxx-envn.yy.dc.oraclezzz.com

As the time of this writing the supported external storage repos are Oracle Cloud Object Storage “Classic” and UCM (Universal Content Manager.

Update: Update 19C now supports OCI (gen2) object storage as well

Step zero: Prerequisites

BICC and UCM privileges need to be configured to obtain permissions:


 Role Hierarchies: Application Implementation Administrator and ESS Administrator, OBIA_EXTRACTTRANSFORMLOAD_RWD

 Role Description: Provide access to schedule the extraction jobs in BIACC

OCI Storage

Create a bucket in OCI console

Get connection details

You need tenancy, user, generate a key, add the key to the user,… (ask an OCI specialist to help you)

Configure & test connection

Create new ICI object Storage Connection
Configure connection appropriately

Create an export and configure External Storage

View results in OCI console

List of generated files with exported data

Download files with OCI CLI

oci os object bulk-download --bucket-name ERPexport --profile eiuenext --auth security_token --namespace eiurenext --download-dir .

Storage Classic

Fist Step: Configure cloud storage

Second Step: Create a connection in the tool

Click the “+” button:

Provide cloud storage information:

Host: <identitydomain>.<region>.storage.oraclecloud.com

Service Name: storage-<identitydomain>

Container: Click the reload button and select a container from the listbox

Third Step: Create an schedule

Click the “+” button and put appropriate values:

Select one or more data stores:

Provide storage connection and the rest of the information and click [Save]

Wait for the job to execute:

Go to object storage console and see what happened:

The zip files contain the data, the JSON files contains details of the job run.

That’s all folks, hope it helps! 🙂

Oracle Loyalty Cloud | REST API | Get Service Requests of a Member + Update SR

Photo by Lukáš Kováčik on Pexels.com

The method for geting this info is under the Engagement REST API here.

The call includes a parameter which is filtering by the Member Name as follows:

curl -X GET -k -H 'Authorization: Basic whatever' -i 'https://serverdomain/crmRestApi/resources/"menbernamehere"&onlyData=true'


curl -X GET -k -H 'Authorization: Basic am9ob........DM3Mzg=' -i 'https://xxxx-xxxx-xx-ext.oracledemos.com/crmRestApi/resources/"ad pepelu"&onlyData=true'

   "items" : [ {
     "SrId" : 300000183643204,
     "SrNumber" : "SR105156",
     "Title" : "bbbbb",
     "ProblemDescription" : null,
     "SeverityCdMeaning" : "High",
     "SeverityCd" : "ORA_SVC_SEV1",
     "AssigneeResourceId" : 300000129858698,
     "PrimaryContactPartyId" : 300000183643142,
     "PrimaryContactPartyUniqueName" : "ad pepelu",
     "PrimaryContactPartyName" : "ad pepelu",
     "ExtnsrMgmtFuseCreateLayout_InstallBase_1554923756871Expr" : "false"
   } ],
   "count" : 1,
   "hasMore" : false,
   "limit" : 25,
   "offset" : 0,
     "name" : "serviceRequests",
     "kind" : "collection"
   } ]

Following same API, here an example of how to update an existing SR:

curl -X PATCH -k -H 'Content-Type: application/vnd.oracle.adf.resourceitem+json' -H 'Authorization: Basic am9ob...3Mzg=' -i 'https://serverdomain/crmRestApi/resources/' --data '{
"ProblemDescription" : "Me duele la cara de ser tan feo"}'
   "SrId" : 300000183643204,
   "SrNumber" : "SR105156",
   "Title" : "bbbbb",
   "ProblemDescription" : "Me duele la cara de ser tan feo",
   "links" : [ {
     "rel" : "self",
     "name" : "resourceMembers",
     "kind" : "collection"
   } ]

Hope it helps! 🙂