09-21-2016 12:55 PM - edited 03-01-2019 06:44 AM
This is an example of creating a input validator in this screen. The inspiration came from the RegEx input validator.
The location for this is in:
Policies -> Orchestration -> Custom Workflow Inputs (select validated input):
Basic Question is how is a new input validator in this screen created:
The next steps will answer that.
Eclipse is needed for the next step to compile the JAVA code.
Notes: This is not an exercise in how to set up Eclipse (please read Eclipse manual for that)
Notes: The inframgr.jar file was copied from the UCSD appliance /opt/infra/inframgr/inframgr.jar
Here is a picture of the over all Eclipse setup (note the left side and oder and placement):
Here is the Java Code:
Note: Yes certain things are hard coded (this is an example one may want to use a credential Policy)
Note: I am using an SSH connection to talk to the UCSD appliance itself to execute a Linux Script)
package com.cloupia.service.cIM.inframgr.customactions.validators;
import com.cloupia.lib.util.ssh.SSHClient;
import com.cloupia.lib.util.ssh.SSHCommandOutput;
//import org.apache.log4j.Logger;
import com.cloupia.service.cIM.inframgr.customactions.UserInputValidatorIf;
public class NameValidatorPreProcessingCustom implements UserInputValidatorIf {
// static Logger logger = Logger.getLogger(NameValidator.class);
String regex = "[\"%&'*+,./:;<=>?^|\\\\]";
public NameValidatorPreProcessingCustom() {
}
@Override
public String getValidatorDescription() {
return "Custom Account name validator (SSH11 Pre Processing)";
}
@Override
public void validateUserInput(String name) throws Exception {
String returnParam = null;
try
{
returnParam = executeCommandThroughSSH( "127.0.0.1", 22, "root", "changeme",
"/tmp/preprocessing.sh", name);
} catch (Exception e) {
//for any exception being thrown by executeCommandThroughSSH,
//overwrite with your execption message
throw new Exception("**** YOUR EXCEPTION MESSAGE GOES HERE (SSh busted)**** ");
}
if ( returnParam != null && returnParam.trim().equals("1") )
throw new Exception("/tmp/preprocessing.sh script returned Error Account Number is not 12345");
}
public String executeCommandThroughSSH(
String host, int port, String userName, String password,
String command, String parameter) throws Exception
{
SSHClient client = new SSHClient(host, port, userName, password);
client.connect();
SSHCommandOutput o = client.executeCommand(command +" "+parameter);
if( o.getExitCode() != 0 )
throw new Exception("Error executing the command");
String stdOut = o.getStdOut();
return stdOut;
}
public static void main(String args[]) {
NameValidatorPreProcessingCustom abc = new NameValidatorPreProcessingCustom();
abc.getValidatorDescription();
System.out.println(abc.getValidatorDescription());
try {
abc.validateUserInput("12345");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
The Linux script is here in /tmp:
Note: Make sure it is chmod +x 'ed
#!/bin/bash
date > /tmp/preprocessing.log
echo $1 >> /tmp/preprocessing.log
if [ "$1" == "12345" ]; then
echo "0"
else
echo "1"
fi
Here are the steps to export the JAR file:
Select Export:
Make next screen look like this:
Make the following screen look like this:
Resulting jar file is attached.
Import the JAR file:
Policies -> Orchestration -> Script Module (DynamicPreProcessingModuleSSH11):
Double click on the newly created item:
Select JAR and hot the green Plus button:
Load the file:
Result:
Register the new functions
The workflow that needs to be run to load the functions:
Note the selector for this workflow to load at UCSD Re-boot:
Custom task to register the code:
//importPackage(java.lang);
//loadJar("DynamicPreProcessingModuleSSH11/DynamicPreProcessingSSH11.jar");
//importPackage(Packages.com.cloupia.service.cIM.inframgr.customactions.validators);
//importClass(com.cloupia.service.cIM.inframgr.customactions.validators.UserInputValidatorRegistry)
//var dynValidator = new Packages.com.cloupia.service.cIM.inframgr.customactions.validators.NameValidatorPreProcessingCustom
//var validatorRegistry = UserInputValidatorRegistry.getInstance();
//validatorRegistry.addValidator(dynValidator.getValidatorDescription(),dynValidator.getClass());
//logger.addInfo( "loaded custom validator: "+dynValidator.getValidatorDescription() );
importPackage(java.lang);
//loadJar("SXSZ/Cisco12345_InputValidator.jar");
loadJar("DynamicPreProcessingModuleSSH11/DynamicPreProcessingSSH11.jar");
importPackage(Packages.com.cloupia.service.cIM.inframgr.customactions.validators.dynamic);
importClass(com.cloupia.service.cIM.inframgr.customactions.validators.UserInputValidatorRegistry)
importClass(com.cloupia.service.cIM.inframgr.customactions.CustomActionUtil)
importClass(com.cloupia.service.cIM.inframgr.customactions.WorkflowInputTypeRegistry)
importClass(com.cloupia.service.cIM.inframgr.customactions.WorkflowInputFieldTypeDeclaration)
//initializing the validator object
//var dynValidator = new Packages.com.cloupia.service.cIM.inframgr.customactions.validators.dynamic.MyCisco12345Validator
var dynValidator = new Packages.com.cloupia.service.cIM.inframgr.customactions.validators.NameValidatorPreProcessingCustom
//get access to validators registry
var validatorRegistry = UserInputValidatorRegistry.getInstance();
//add the new validator within the validator registry
validatorRegistry.addValidator(dynValidator.getValidatorDescription(),dynValidator.getClass());
logger.addInfo( "loaded custom validator: "+dynValidator.getValidatorDescription() );
//get list of custom input types used within UCSD
var customInputTypesList = CustomActionUtil.getWFCustomLOVInputs();
//get access to all input types registry
var wfInputRegistry = WorkflowInputTypeRegistry.getInstance();
//iterate over custom wf input types
for(var i=0;i<customInputTypesList.size();i++)
{
var WFCustomLovInputType = customInputTypesList.get(i);
var validatorNameSetWithinCustomWfInput = WFCustomLovInputType.getValidator();
//if we have a custom input type which makes use of the current validator
if( dynValidator.getValidatorDescription().equals(validatorNameSetWithinCustomWfInput) )
{
var customWfInputName = WFCustomLovInputType.getWfinputType();
//retrieve the declaration for the custom input type
var customWfInputDeclaration = wfInputRegistry.getDeclaration(customWfInputName);
//ensure we set the validator within the input type declaration
customWfInputDeclaration.setValidator( dynValidator.getClass().newInstance() );
}
}
Workflow is attached and workflow run:
Creating the custom variable:
Test workflow for input variable:
Workflow execution:
UCSD 6.0 End user look and feel:
Log file:
[root@localhost tmp]# cat preprocessing.log
Wed Sep 21 22:55:01 UTC 2016
abc
[root@localhost tmp]#
Log file with correct input:
[root@localhost tmp]# cat preprocessing.log
Wed Sep 21 22:57:10 UTC 2016
12345
[root@localhost tmp]#
Workflow is attached.
Incase some one wants to handle this via open automation vs. script module here is the code to register the new validator:
Registration code below:
package com.cloupia.feature.customLacValidators;
import java.util.List;
import org.apache.log4j.Logger;
import com.cloupia.service.cIM.inframgr.AbstractCloupiaModule;
import com.cloupia.service.cIM.inframgr.AbstractTask;
import com.cloupia.service.cIM.inframgr.CustomFeatureRegistry;
import com.cloupia.service.cIM.inframgr.collector.controller.CollectorFactory;
import com.cloupia.service.cIM.inframgr.customactions.CustomActionUtil;
import com.cloupia.service.cIM.inframgr.customactions.WFCustomLovInput;
import com.cloupia.service.cIM.inframgr.customactions.validators.UserInputValidatorRegistry;
import com.cloupia.service.cIM.inframgr.customactions.WorkflowInputTypeRegistry;
import com.cloupia.service.cIM.inframgr.customactions.WorkflowInputFieldTypeDeclaration;
import com.cloupia.service.cIM.inframgr.customactions.lacValidators.AccountNumber;
import com.cloupia.service.cIM.inframgr.customactions.lacValidators.VMName;
import com.cloupia.service.cIM.inframgr.reports.simplified.CloupiaReport;
public class customLacValidatorsModule extends AbstractCloupiaModule {
public static final String CUSTOM_INDICATOR = "CUSTOM ";
public static final String VALIDATOR_ACCOUNT_NAME = "LAC Account Validator";
public static final String VALIDATOR_VM_NAME = "LAC VM Validator";
private static Logger logger = Logger.getLogger(customLacValidatorsModule.class);
public customLacValidatorsModule() {
// TODO Auto-generated constructor stub
}
@Override
public CollectorFactory[] getCollectors() {
// This class provides the ability to load and register dynamic
// field validators, therefore this class does not contain collectors
return null;
}
@Override
public CloupiaReport[] getReports() {
// This class provides the ability to load and register dynamic
// field validators, therefore this class does not contain reports
return null;
}
@Override
public AbstractTask[] getTasks() {
// This class provides the ability to load and register dynamic
// field validators, therefore this class does not contain tasks
return null;
}
@Override
public void onStart(CustomFeatureRegistry arg0) {
// TODO add method call to another class for the registrations here?
UserInputValidatorRegistry validatorRegistry = UserInputValidatorRegistry.getInstance();
AccountNumber acctValidator = new AccountNumber();
validatorRegistry.addValidator(VALIDATOR_ACCOUNT_NAME,acctValidator.getClass());
logger.info(CUSTOM_INDICATOR + "Loaded custom validator: "+VALIDATOR_ACCOUNT_NAME+": " +acctValidator.getValidatorDescription() );
VMName vmValidator = new VMName();
validatorRegistry.addValidator(VALIDATOR_VM_NAME,vmValidator.getClass());
logger.info(CUSTOM_INDICATOR + "Loaded custom validator: "+VALIDATOR_VM_NAME+": " +vmValidator.getValidatorDescription() );
//get list of custom input types used within UCSD
List<WFCustomLovInput> customInputTypesList = null;
try {
customInputTypesList = CustomActionUtil.getWFCustomLOVInputs();
} catch (Exception e) {
logger.error(CUSTOM_INDICATOR + "Could not obtain custom input list. Custom field validations will not function properly.");
e.printStackTrace();
}
//get access to all input types registry
WorkflowInputTypeRegistry wfInputRegistry = WorkflowInputTypeRegistry.getInstance();
//iterate over custom wf input types
for (int i=0;i<customInputTypesList.size();i++)
{
WFCustomLovInput WFCustomLovInputType = customInputTypesList.get(i);
String validatorNameSetWithinCustomWfInput = WFCustomLovInputType.getValidator();
//if we have a custom input type which makes use of the current VALIDATOR_ACCOUNT_NAME validator
if( VALIDATOR_ACCOUNT_NAME.equals(validatorNameSetWithinCustomWfInput) )
{
String customWfInputName = WFCustomLovInputType.getWfinputType();
//retrieve the declaration for the custom input type
WorkflowInputFieldTypeDeclaration customWfInputDeclaration = wfInputRegistry.getDeclaration(customWfInputName);
//ensure we set the validator within the input type declaration
customWfInputDeclaration.setValidator(acctValidator);
}
//if we have a custom input type which makes use of the current VALIDATOR_VM_NAME validator
if( VALIDATOR_VM_NAME.equals(validatorNameSetWithinCustomWfInput) )
{
String customWfInputName = WFCustomLovInputType.getWfinputType();
//retrieve the declaration for the custom input type
WorkflowInputFieldTypeDeclaration customWfInputDeclaration = wfInputRegistry.getDeclaration(customWfInputName);
//ensure we set the validator within the input type declaration
customWfInputDeclaration.setValidator(vmValidator);
}
}
}
}
Bash Script Example to test for different RegEx :
cat preprocessingregex.sh
#!/bin/bash
date > /tmp/preprocessingregex.log
echo $1 >> /tmp/preprocessingregex.log
a="No Match"
#
# test for San Francisco
#
[[ $1 =~ ^SFO[0-9]{3}$ ]] && a="SFO match"
#
# test for New York
#
[[ $1 =~ ^NY[0-9]{3}$ ]] && a="New York match"
#
# test for Chicago
#
[[ $1 =~ ^ORD[0-9]{3}$ ]] && a="Chicago match"
echo $a
Another version of bash script:
#!/bin/bash
date > /tmp/preprocessingregex.log
echo $0 >> /tmp/preprocessingregex.log
echo $1 >> /tmp/preprocessingregex.log
#
# test for server name existance
#
export c=`grep -m1 "^$1$" /tmp/servers.txt | wc -l`
if [ $c -gt 0 ]; then
a="40"
echo $a
exit
fi
a="1"
#
# test for San Francisco
#
# Start with SFO and followed by any char
if [[ $1 =~ ^[S][F][O].*$ ]]; then
if [[ $1 =~ ^[S][F][O][0-9]{3}$ ]]; then
# Adheres to SFO regex
a="0"
echo $a
exit
else
# Started with SFO but does not adhere to SFO regex(1)
a="10"
echo $a
exit
fi
fi
#
# test for New York
#
# Start with NY and followed by any char
if [[ $1 =~ ^[N][Y].*$ ]]; then
if [[ $1 =~ ^[N][Y][0-9]{3}$ ]]; then
# Adheres to NY regex
a="0"
echo $a
exit
else
# Started with NY but does not adhere to NY regex(1)
a="20"
echo $a
exit
fi
fi
#
# test for Chicago
#
# Start with ORD and followed by any char
if [[ $1 =~ ^[O][R][D].*$ ]]; then
if [[ $1 =~ ^[O][R][D][0-9]{3}$ ]]; then
# Adheres to ORD regex
a="0"
echo $a
exit
else
# Started with ORD but does not adhere to ORD regex(1)
a="30"
echo $a
exit
fi
fi
# if a is still set to 1 then it did not adhere to any statements above
echo $a
Another Example:
The Bash script:
[root@localhost tmp]# cat runtime.sh
#!/bin/bash
date > /tmp/runtime.sh.log
echo $0 >> /tmp/runtime.sh.log
echo $1 >> /tmp/runtime.sh.log
a="Did not adhere to any RegEx statements..."
#
# test for server name existance
#
export c=`grep $1 /tmp/servers.txt | wc -l`
if [ $c -gt 0 ]; then
a="Server Name found in /tmp/server.txt"
echo $a
exit
fi
#
# test for San Francisco
#
# Start with SFO and followed by any char
if [[ $1 =~ ^[S][F][O].*$ ]]; then
if [[ $1 =~ ^[S][F][O][0-9]{3}$ ]]; then
# Adheres to SFO regex
a="0"
echo $a
exit
else
a="Started with SFO but does not adhere to SFO regex(1)"
echo $a
exit
fi
fi
#
# test for New York
#
# Start with NY and followed by any char
if [[ $1 =~ ^[N][Y].*$ ]]; then
if [[ $1 =~ ^[N][Y][0-9]{3}$ ]]; then
# Adheres to NY regex
a="0"
echo $a
exit
else
a="Started with NY but does not adhere to NY regex(1)"
echo $a
exit
fi
fi
#
# test for Chicago
#
# Start with ORD and followed by any char
if [[ $1 =~ ^[O][R][D].*$ ]]; then
if [[ $1 =~ ^[O][R][D][0-9]{3}$ ]]; then
# Adheres to ORD regex
a="0"
echo $a
exit
else
a="Started with ORD but does not adhere to ORD regex(1)"
echo $a
exit
fi
fi
# if a is still set to 1 then it did not adhere to any statements above
echo $a
The Java Code:
package com.cloupia.service.cIM.inframgr.customactions.validators;
import com.cloupia.lib.util.ssh.SSHClient;
import java.io.*;
import com.cloupia.lib.util.ssh.SSHCommandOutput;
//import org.apache.log4j.Logger;
import com.cloupia.service.cIM.inframgr.customactions.UserInputValidatorIf;
public class NameValidatorPreProcessingCustom implements UserInputValidatorIf {
// static Logger logger = Logger.getLogger(NameValidator.class);
String regex = "[\"%&'*+,./:;<=>?^|\\\\]";
public NameValidatorPreProcessingCustom() {
}
@Override
public String getValidatorDescription() {
return "Custom Account name validator (SSH20 Pre Processing)";
}
@Override
public void validateUserInput(String name) throws Exception {
String s = null;
try
{
Process p = Runtime.getRuntime().exec("/tmp/runtime.sh "+name);
BufferedReader stdInput = new BufferedReader(new InputStreamReader(p.getInputStream()));
s = stdInput.readLine();
}catch (Exception e) {
throw new Exception("**** Runtime EXEC hat issue (20)**** ");
}
if ( s != null && !s.trim().equals("0") )
throw new Exception("Error >"+s+"<");
/*
String returnParam = null;
try
{
returnParam = executeCommandThroughSSH( "127.0.0.1", 22, "root", "cloupia123",
"/tmp/preprocessingregex.sh", name);
} catch (Exception e) {
//for any exception being thrown by executeCommandThroughSSH,
//overwrite with your execption message
throw new Exception("**** SSH to localhost had issues (18)**** ");
}
if ( returnParam != null && returnParam.trim().equals("1") )
throw new Exception("/tmp/preprocessingregex.sh Error does not adhere to any RegEx (18) ");
if ( returnParam != null && returnParam.trim().equals("10") )
throw new Exception("/tmp/preprocessingregex.sh Error does not adhere to SFO RegEx (18) ");
if ( returnParam != null && returnParam.trim().equals("20") )
throw new Exception("/tmp/preprocessingregex.sh Error does not adhere to NY RegEx (18) ");
if ( returnParam != null && returnParam.trim().equals("30") )
throw new Exception("/tmp/preprocessingregex.sh Error does not adhere to ORD RegEx (18) ");
if ( returnParam != null && returnParam.trim().equals("40") )
throw new Exception("/tmp/preprocessingregex.sh /tmp/servers.txt Server Name Exists already (18) ");
*/
}
public String executeCommandThroughSSH(
String host, int port, String userName, String password,
String command, String parameter) throws Exception
{
SSHClient client = new SSHClient(host, port, userName, password);
client.connect();
SSHCommandOutput o = client.executeCommand(command +" "+parameter);
if( o.getExitCode() != 0 )
throw new Exception("Error executing the command");
String stdOut = o.getStdOut();
return stdOut;
}
public static void main(String args[]) {
NameValidatorPreProcessingCustom abc = new NameValidatorPreProcessingCustom();
abc.getValidatorDescription();
System.out.println(abc.getValidatorDescription());
try {
abc.validateUserInput("12345");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
More Generic JAVA code (also attached jar file)
package com.cloupia.service.cIM.inframgr.customactions.validators;
import com.cloupia.lib.util.ssh.SSHClient;
import java.io.*;
import com.cloupia.lib.util.ssh.SSHCommandOutput;
//import org.apache.log4j.Logger;
import com.cloupia.service.cIM.inframgr.customactions.UserInputValidatorIf;
public class NameValidatorPreProcessingCustom implements UserInputValidatorIf {
// static Logger logger = Logger.getLogger(NameValidator.class);
String regex = "[\"%&'*+,./:;<=>?^|\\\\]";
public NameValidatorPreProcessingCustom() {
}
@Override
public String getValidatorDescription() {
return "Custom Bash Validation (/usr/local/bin/UCSDPreProcessingRuntime.sh)";
}
@Override
public void validateUserInput(String name) throws Exception {
String s = null;
try
{
Process p = Runtime.getRuntime().exec("/usr/local/bin/UCSDPreProcessingRuntime.sh "+name);
BufferedReader stdInput = new BufferedReader(new InputStreamReader(p.getInputStream()));
s = stdInput.readLine();
}catch (Exception e) {
throw new Exception("**** Check file /usr/local/bin/UCSDPreProcessingRuntime.sh **** ");
}
if ( s != null && !s.trim().equals("0") )
throw new Exception(s);
/*
String returnParam = null;
try
{
returnParam = executeCommandThroughSSH( "127.0.0.1", 22, "root", "cloupia123",
"/tmp/preprocessingregex.sh", name);
} catch (Exception e) {
//for any exception being thrown by executeCommandThroughSSH,
//overwrite with your execption message
throw new Exception("**** SSH to localhost had issues (18)**** ");
}
if ( returnParam != null && returnParam.trim().equals("1") )
throw new Exception("/tmp/preprocessingregex.sh Error does not adhere to any RegEx (18) ");
if ( returnParam != null && returnParam.trim().equals("10") )
throw new Exception("/tmp/preprocessingregex.sh Error does not adhere to SFO RegEx (18) ");
if ( returnParam != null && returnParam.trim().equals("20") )
throw new Exception("/tmp/preprocessingregex.sh Error does not adhere to NY RegEx (18) ");
if ( returnParam != null && returnParam.trim().equals("30") )
throw new Exception("/tmp/preprocessingregex.sh Error does not adhere to ORD RegEx (18) ");
if ( returnParam != null && returnParam.trim().equals("40") )
throw new Exception("/tmp/preprocessingregex.sh /tmp/servers.txt Server Name Exists already (18) ");
*/
}
public String executeCommandThroughSSH(
String host, int port, String userName, String password,
String command, String parameter) throws Exception
{
SSHClient client = new SSHClient(host, port, userName, password);
client.connect();
SSHCommandOutput o = client.executeCommand(command +" "+parameter);
if( o.getExitCode() != 0 )
throw new Exception("Error executing the command");
String stdOut = o.getStdOut();
return stdOut;
}
public static void main(String args[]) {
NameValidatorPreProcessingCustom abc = new NameValidatorPreProcessingCustom();
abc.getValidatorDescription();
System.out.println(abc.getValidatorDescription());
try {
abc.validateUserInput("12345");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Generic Input Validator Installation (tested on UCSD 6.0):
============================================
Create script module named: CustomBashValidation
Policies -> Orchestration -> Script Module
Import jar file into script module: CustomBashValidation_v1.jar
Policies -> Orchestration -> Script Module -> CustomBashValidation -> JAR -> ADD
Import workflow: CustomBashValidation_v1_Loader.wfdx (unzip first!)
Policies -> Orchestration -> Workflows -> Import
Run workflow to load new validator: LoadCustomBashValidation_v1_wf1
Download UCSDPREProcessingRuntime.sh and copy to UCSD instance to /usr/local/bin/UCSDPreProcessingRuntime.sh
chmod +x /usr/local/bin/UCSDPreProcessingRuntime.sh
create file to check if a server names does exist:
(in this customer instance the file gets created from many different locations and the result ends up in /tmp/servers.txt):
/tmp/servers.txt
ORD111
SFO111
NY111
ORD222
SFO222
SFO333
Create custom workflow input validator and use new Bash validator
Policies -> Orchestration -> Custom Workflow Input
Variable: Servers
Type: generic text
Validator:
Create workflow and use newly create variable Servers
Test with:
Find answers to your questions by entering keywords or phrases in the Search bar above. New here? Use these resources to familiarize yourself with the community: