Cybersecurity
DevOps Cloud
IT Operations Cloud
At times, we need to create or obtain a value from a shell script for use in later process steps. Here is an example of one simple way to accomplish this.
In our example, we will assume that we have a component and the component versions are coming from Dimensions baselines. Therefore, the component version name may be rather elaborate. In our example we will assume that the baselines are created from a Dimensions Change Request and the baseline name begins with the change request name.
We will assume that we must capture this change request identifier and extract it from the baseline name (or version name) for use later in the process.
Therefore, we have a component, I’ve named this SDA component: SetPropFromShellVar.
I have established the source type of the component and imported at least one version. My first version has the name: BRK_CR_45632_BL201605291500. The first portion is the CR identifier: BRK_CR_45632.
In order to obtain a value from shell script output, we will need to modify the post processing scanner used by our shell script step. Within our shell script process step, we will perform our string functions and end up with a shell variable that contains the desired string that we wish to place into a property. At the end of our shell script step, we will add a line to perform an echo of this variable to the output log. For our example, we’ll assume that we are running this process on a Windows agent. Let’s say that our shell script step will contain this statement:
echo CRNAME=%crname%
So, within SDA, we’ll want to navigate to Administration | Automations | Post Processing Scripts. Click the icon on the right to add a new post processing script, give the script a name and fill in the description if you wish.
For the Script Body, our significant addition will be something like this:
properties.put("Status", "Success");
var process = [];
scanner.register("^(?i)CRName:", function(lineNumber, line) {
var CRName = line.replace("CRNAME:","");
properties.put("BL_CRNAME", CRName);
});
The above will register a scanner that will search (case insensitive) the output log for CRName: and when it is found, the remainder of the line will become the value of a an output property created on a process step. The name of that output property will be BL_CRNAME.
Of course, if may be wise to add other scanners to the post processing script to catch other errors. I have all of the following in my post processing script for this example:
properties.put("Status", "Success");
var process = [];
scanner.register("^(?i)CRName:", function(lineNumber, line) {
var CRName = line.replace("CRNAME:","");
properties.put("BL_CRNAME", CRName);
});
scanner.register("(?i)Error", function(lineNumber, line) {
properties.put("exitCode", "1");
properties.put("Status", "Failure");
var value = line.replace("Msg ", "Msg")
properties.put("Msg", value);
});
scanner.register("(?i)Failed", function(lineNumber, line) {
properties.put("exitCode", "1");
properties.put("Status", "Failure");
var value = line.replace("Msg ", "Msg")
properties.put("Msg", value);
});
scanner.register("Caught:", function(lineNumber, line) {
properties.put("exitCode", "1");
properties.put("Status", "Failure");
var value = line.replace("Msg ", "Msg")
properties.put("Msg", value);
});
scanner.scan();
var errors = properties.get("Msg");
if (errors == null) {
errors = new java.util.ArrayList();
} else {
properties.put("exitCode", "1");
properties.put("Status", "Failure");
}
When you have completed your post processing script (or copied and modified the above) then save it.
Now, return to your component (Management | Components | . My first process step is to download the component. Usually I will accept the default process step properties.
My second process step is a shell script process. I named my process step: GET_CR_NAME.
My shell script body is:
for /f "tokens=1,2,3 delims=_" %%a in ("${p:version.name}") do set prod=%%a&set crtype=%%b&set seqnbr=%%c
set crname="%prod%_%crtype%_%seqnbr%"
echo CRNAME:%crname%
Also, on the process step properties page, locate the property named “Post Processing Script”. Select the script that was created earlier.
NOTE: Regarding above shell script operation. A Dimensions CM request ID is formatted as follows:
__
The baseline name is established at the time of creation and can be almost any string desired. In our example environment, convention dictates that the baseline name starts with the change request number and also includes a date/time string. Therefore, the change request number is obtained by extracting everything from the beginning of the string until the 3rd underline character. The statements above accomplish this. A similar script for Unix/Linux shell could also be constructed.
Now, if you wish, you may end things here, and connect the process steps. After this runs, the value may be seen by examining the output properties of the shell script process step. If there are further steps, the property can be referenced by an other process steps within this same process by referencing the name of the process step and the given property name (from the post processing script). Therefore, in my example, the property may be referenced as: ${p:Get_CR_Name/BL_CRNAME}.
It is also possible to utilize the Serena DA plugin steps to create or update a property. For example, Create Component Property. In this example, each component version will be derived from a different Dimensions CM baseline and thus a different change request, it would not make much sense to apply such a property to the entire component. It would make more sense to utilize a component version property. In a future post I will outline how to create that property, how to find it in the propsheets and how to update the value for a single component version from within a process step.