Table of Content
In Part1 we start with the SQL DB Plugin and create the required database for our need.
In Part2 we start with the development of our Workflow. We will start with a few elements.
In Part3 we finish the collection of the VM information.
In Part4 we insert our data into the database and test our created workflow
In Part5 we create our webview to get a look on our Data in the SQL Database
In Part6 we will make our Workflow smarter to update the DB with actual VM information
In Part7 problems with vAPP located virtual machines are fixed
Part6
Let’s have a look on our LittleCMDB. We can capture virtual machines, we insert the captured data into a SQL DB and we have a Website to get a look on our data. Till now, that okay but we have some “problems” with our CMDB. What’s with virtual Machines were the configuration is changed after the first capture? At the moment will we not get this configuration changes. Why we don’t get the changes? In our decision “VM in DB” we have the condition “when the VM is in our DB we go back to NumberofVMs”. We don’t look for configuration changes.
That’s not smart 🙂 ……… This means our DB could be outdated with one week if enough configuration changes were made…
So let’s start and make our LittleCMDB more “production” ready.
First we remove the red dotted line from “VM in DB” to “NumberofVMs”.
First we insert from Bottom to top a Scriptable Task and a Decision. We do this four times. When we are finished your schema should look like mine.
Then we will insert the next Workflows. Here we are on a decision we must made…… We can choose the SQL “Update” workflows or generate Scriptable Task with our own code. I will use scriptable task for the update of the datasets. Why that? When you use the “Update” Workflows, error correction and data search is sometimes a problem. You can only insert “one” value (the value to update the dataset). In the data search, this leads to problems. So I will use scriptable task in which I can insert all needed parameter and my required error correction.
So insert four scriptable workflows on the left of the other workflows.
At the End your schema must look like this:
Don’t worry about the sum of Workflow……it will be very easy 😉
Know we start with the Scriptable Task at the bottom. First we give a name and description. I will call it “GetVMfromVM_Info”. As description you can insert “We read the information from the VM_Info Table split it and comparing it with the actual data.”
Here are the required Variables for the Element:
Local Parameter | Variable Name | Module | Direction | Type |
VMName | VMName | GetVMInfofromVM_Info | in | String |
VMInfo_Table | VMInfo_Table | GetVMInfofromVM_Info | in | SQL:Table |
VMUUID | VMUUID | GetVMInfofromVM_Info | in | String |
VMInfofromDB | VMInfofromDB | GetVMInfofromVM_Info | in | SQL:ActiveRecord |
datastoreName | datastoreName | GetVMInfofromVM_Info | in | Array/string |
cpuCount | cpuCount | GetVMInfofromVM_Info | in | number |
memoryMB | memoryMB | GetVMInfofromVM_Info | in | number |
CPUNumberfromDB | CPUNumberfromDB | GetVMInfofromVM_Info | out | number |
MemNumberfromDB | MemNumberfromDB | GetVMInfofromVM_Info | out | number |
VM_Info_Change | VM_info_Change | GetVMInfofromVM_Info | out | Boolean |
V_ID | V_ID | GetVMInfofromVM_Info | Out | String |
Don’t forget to map the VMInfo_table variable to the VM_Info table.
Here is the required Script for the Task:
// ------------------------------------------------------------- // we search for the Data of the virtual Machine with the Name and the UUID. First we define the search columns var columns = { VMUUID : VMUUID, VMName : VMName, }; // Get the Data from the Table and put them in a SQL Active Record VMInfofromDB = VMInfo_table.readRecords(columns); // The data from the SQL Record is a "String" with is separated with ",". We have to Split the String in Single Files..... // First, we put the String into a temporally Variable. var SplitConfigArraytoStringMem = VMInfofromDB.toString(); // In the Array, we search for the Keyword "MemConfig" under which our Memory configuration is stored var MemSearch = SplitConfigArraytoStringMem.search("MemConfig"); // The above defined search give us the Starting Position of our Keyword. We want the blank value, so we have to split // on Position 10 after the Start Position (MemConfig + = is about 10 positions) var MemStart = MemSearch + 10; // Here we split at the beginning of the Value with the rest of the string var MemStringTemp = SplitConfigArraytoStringMem.slice(MemStart); // We split on the first "," found. That's our value End var MemStringEnd = MemStringTemp.search(","); // Here we take the start and the end we figured out before and save the value into the Variable MemNumberfromDB = MemStringTemp.slice(0, MemStringEnd); // The data from the SQL Record is a "String" with is sepearted with ",". We have to Split the String in Single Files..... // First, we put the String into a temporally Variable. var SplitConfigArraytoStringCPU = VMInfofromDB.toString(); // In the Array, we search for the Keyword "CPUConfig" under which our Memory configuration is stored var CPUSearch = SplitConfigArraytoStringCPU.search("CPUConfig"); // The above defined search give us the Starting Position of our Keyword. We want the blank value, so we have to split // on Position 10 after the Start Position (CPUConfig + = is about 10 positions) var CPUStart = CPUSearch + 10; // Here we split at the beginning of the Value with the rest of the string var CPUStringTemp = SplitConfigArraytoStringCPU.slice(CPUStart); // We split on the first "}" found. That's our value End var CPUStringEnd = CPUStringTemp.search("}"); // Here we take the start and the end we figured out before and save the value into the Variable CPUNumberfromDB = CPUStringTemp.slice(0, CPUStringEnd); // The data from the SQL Record is a "String" with is sepearted with ",". We have to Split the String in Single Files..... // First, we put the String into a temporally Variable. // The V_ID Field is required to update the SQL DB when there is a change var SplitConfigArraytoStringVID = VMInfofromDB.toString(); // In the Array, we search for the Keyword "V_ID" under which our V_ID is stored var VIDSearch = SplitConfigArraytoStringVID.search("VMID"); // The above defined search give us the Starting Position of our Keyword. We want the blank value, so we have to split // on Position 5 after the Start Position (VMID + = is about 5 positions) var VIDStart = VIDSearch + 5; // Here we split at the beginning of the Value with the rest of the string var VIDStringTemp = SplitConfigArraytoStringVID.slice(VIDStart); // We split on the first "," found. That's our value End var VIDStringEnd = VIDStringTemp.search(","); // Here we take the start and the end we figured out before and save the value into the Variable V_ID = VIDStringTemp.slice(0, VIDStringEnd); //----------------------------------------------------------------------------------------------------------------- // After we have our "configuration" Values, we have to check if there is a difference between the VM Data and // the data stored in the DB. if ((CPUNumberfromDB != cpuCount) || (MemNumberfromDB != memoryMB)){ // When there is a difference, we set the Variable to true VM_Info_Change = true;} else { // When there is no difference, we set the Variable to false VM_Info_Change = false;}
I made a lot comments in the scripting element so I hope everybody understand the Idea to split the array and get on the DB data.
Next we go to our decision up to the scripting element. We give it a name. I chose “VM_Info_change”. As variable for this decision we need the following:
Local Parameter | Variable Name | Module | Direction | Type |
VM_Info_Change | VM_Info_Change | VM_Info_Change | in | boolean |
In the Decision field we set the Value to “is true”
At least, we are going to work with the “Scriptable task” to the left. I call it “Update active record for ‘VM_Info’” Element. For that, we need the following In- and Outputs
Local Parameter | Variable Name | Module | Direction | Type |
VMName | VMName | Update Active Record for ‘VM_Info’ | in | String |
V_ID | V_ID | Update Active Record for ‘VM_Info’ | in | String |
VMUUID | VMUUID | Update Active Record for ‘VM_Info’ | in | String |
cpuCount | cpuCount | Update Active Record for ‘VM_Info’ | in | Number |
memoryMB | memoryMB | Update Active Record for ‘VM_Info’ | in | Number |
MemNumberfromDB | MemNumberfromDB | Update Active Record for ‘VM_Info’ | in | Number |
CPUNumberfromDB | CPUNumberfromDB | Update Active Record for ‘VM_Info’ | in | Number |
VMInfo_table | VMInfo_table | Update Active Record for ‘VM_Info’ | in | SQL:Table |
VMInfoRead_result | VMInfoRead_result | Update Active Record for ‘VM_Info’ | in | SQL:ActiveRecord |
UpdateResult_VM_Info | UpdateResult_VM_Info | Update Active Record for ‘VM_Info’ | out | Number |
Here is the script we insert into the Scripting field:
// we need the original values to load the record from the DB var NewArray = new Array(V_ID,VMUUID,VMName,CPUNumberfromDB,MemNumberfromDB) // we search for the record in the DB with the data from there VMInfoRead_result = System.getModule("com.vmware.library.sql").findUniqueRecord(VMInfo_table,NewArray); var columns = { VMID : V_ID, VMUUID : VMUUID, VMName : VMName, CPUConfig : cpuCount, MemConfig : memoryMB }; UpdateResult_VM_Info = VMInfo_table.updateRecord(VMInfoRead_result, columns); System.log("Update DB with new virtual machine information")
Now we are going to connect the first Elements. We start with the “VM_in_DB” Element and connect it with the “red” line to the “GetVMfromVM_Info” Element. The “GetVMfromVM_Info” will be connected to the “VM_Info_Change” element. From this element we connect the “true” (the green line) to “Update active record for ‘VM_Info” and the “false” (the red line) to the “Scriptable Task above. As last connection we draw the line from “Update active record for ‘VM_Info” to the Scriptable Task above. When you are ready your connections must look like my.
After we have finished our connections, we go further with the “Scriptable Task” Element we have already connected. First we insert a name and description. I use as name “GetVMfromHost_info” and as description “Get the Information from the database regarding the Host information”. Then we have to define our needed variables:
Local Parameter | Variable Name | Module | Direction | Type |
VMHost_Table | VMHost_Table | GetVMfromHost_info | in | SQL:Table |
VMUUID | VMUUID | GetVMfromHost_info | in | String |
V_ID | V_ID | GetVMfromHost_info | in | string |
VMInfofromDB | VMInfofromDB | GetVMfromHost_info | in | SQL:ActiveRecord |
runningHostName | runningHostName | GetVMfromHost_info | in | String |
clusterName | clusterName | GetVMfromHost_info | in | String |
resourcePoolName | resourcePoolName | GetVMfromHost_info | in | String |
folderName | folderName | GetVMfromHost_info | in | String |
HostfromDB | HostfromDB | GetVMfromHost_info | out | String |
ClusterfromDB | ClusterfromDB | GetVMfromHost_info | out | String |
RPfromDB | RPfromDB | GetVMfromHost_info | out | String |
FolderfromDB | FolderfromDB | GetVMfromHost_info | out | String |
VM_Host_Change | VM_Host_Change | GetVMfromHost_info | out | boolean |
Also here is it required, to point the Variable “VMHost_table” to the “VM_Host” Table
Then we can start our scripting. In the basic, the following scripting is the same as we already did for the “GetVMInfofromVM_Info” table. Here is the Script:
// ------------------------------------------------------------- // we search for the Data of the virtual Machine with the Name and the UUID. First we define the search columns var columns = { VMID : V_ID, VMUUID : VMUUID, }; // Get the Data from the Table and put them in a SQL Active Record VMInfofromDB = VMHost_table.readRecords(columns); // The data from the SQL Record is a "String" with is sepearted with ",". We have to Split the String in Single Files..... // First, we put the String into a temporally Variable. var SplitConfigArraytoStringHost = VMInfofromDB.toString(); // In the Array, we search for the Keyword var HostSearch = SplitConfigArraytoStringHost.search("Host"); // The above defined search give us the Starting Position of our Keyword. We want the blank value, so we have to split // on Position 5 after the Start Position var HostStart = HostSearch + 5; // Here we split at the beginning of the Value with the rest of the string var HostStringTemp = SplitConfigArraytoStringHost.slice(HostStart); // We split on the first "," found. That's our value End var HostStringEnd = HostStringTemp.search(","); // Here we take the start and the end we figured out before and save the value into the Variable HostfromDB = HostStringTemp.slice(0, HostStringEnd); // The data from the SQL Record is a "String" with is sepearted with ",". We have to Split the String in Single Files..... // First, we put the String into a temporally Variable. var SplitConfigArraytoStringCluster = VMInfofromDB.toString(); // In the Array, we search for the Keyword var ClusterSearch = SplitConfigArraytoStringCluster.search("Cluster"); // The above defined search give us the Starting Position of our Keyword. We want the blank value, so we have to split // on Position 8 after the Start Position var ClusterStart = ClusterSearch + 8; // Here we split at the beginning of the Value with the rest of the string var ClusterStringTemp = SplitConfigArraytoStringCluster.slice(ClusterStart); // We split on the first "}" found. That's our value End var ClusterStringEnd = ClusterStringTemp.search(","); // Here we take the start and the end we figured out before and save the value into the Variable ClusterfromDB = ClusterStringTemp.slice(0, ClusterStringEnd); // The data from the SQL Record is a "String" with is sepearted with ",". We have to Split the String in Single Files..... // First, we put the String into a temporally Variable. var SplitConfigArraytoStringFolder = VMInfofromDB.toString(); // In the Array, we search for the Keyword var FolderSearch = SplitConfigArraytoStringFolder.search("Folder"); // The above defined search give us the Starting Position of our Keyword. We want the blank value, so we have to split // on Position 7 after the Start Position var FolderStart = FolderSearch + 7; // Here we split at the beginning of the Value with the rest of the string var FolderStringTemp = SplitConfigArraytoStringCluster.slice(FolderStart); // We split on the first "," found. That's our value End var FolderStringEnd = FolderStringTemp.search(","); // Here we take the start and the end we figured out before and save the value into the Variable FolderfromDB = FolderStringTemp.slice(0, FolderStringEnd); // The data from the SQL Record is a "String" with is sepearted with ",". We have to Split the String in Single Files..... // First, we put the String into a temporally Variable. var SplitConfigArraytoStringRP = VMInfofromDB.toString(); // In the Array, we search for the Keyword var RPSearch = SplitConfigArraytoStringRP.search("ResourcePool"); // The above defined search give us the Starting Position of our Keyword. We want the blank value, so we have to split // on Position 13 after the Start Position var RPStart = RPSearch + 13; // Here we split at the beginning of the Value with the rest of the string var RPStringTemp = SplitConfigArraytoStringRP.slice(RPStart); // We split on the first "}" found. That's our value End var RPStringEnd = RPStringTemp.search("}"); // Here we take the start and the end we figured out before and save the value into the Variable RPfromDB = RPStringTemp.slice(0, RPStringEnd); //----------------------------------------------------------------------------------------------------------------- // After we have our "configuration" Values, we have to check if there is a difference between the VM Data and // the data stored in the DB. if ((HostfromDB != runningHostName) || (ClusterfromDB != clusterName) || (RPfromDB != resourcePoolName) || (FolderfromDB != folderName)){ // When there is a difference, we set the Variable to true VM_Host_Change = true;} else { // When there is no difference, we set the Variable to false VM_Host_Change = false;}
After we finished our scripting we went to the “Decision”. Here we enter a name; I use “VM_Host_Change” and a description. In the Decision we need the Variable “Vm_Host_Change”
Local Parameter | Variable Name | Module | Direction | Type |
VM_Host_Change | VM_Host_Change | VM_Host_Change | in | boolean |
We set the Value in the Decision field to “is true”.
Next we define the In- and Outputs for the “Scriptable Task”. I call the Workflow “Update active record for ‘VM_Host’”. We need the following variables:
Local Parameter | Variable Name | Module | Direction | Type |
V_ID | V_ID | Update Active Record for ‘VM_Host’ | in | String |
VMUUID | VMUUID | Update Active Record for ‘VM_Host’ | in | String |
clusterName | clusterName | Update Active Record for ‘VM_Host’ | in | String |
runningHostName | runningHostName | Update Active Record for ‘VM_Host’ | in | String |
resourcePoolName | resourcePoolName | Update Active Record for ‘VM_Host’ | in | String |
folderName | folderName | Update Active Record for ‘VM_Host’ | in | String |
ClusterfromDB | ClusterfromDB | Update Active Record for ‘VM_Host’ | in | String |
HostfromDB | HostfromDB | Update Active Record for ‘VM_Host’ | in | String |
RPfromDB | RPfromDB | Update Active Record for ‘VM_Host’ | in | String |
FolderfromDB | FolderfromDB | Update Active Record for ‘VM_Host’ | in | String |
UpdateResult_VM_Host | UpdateResult_VM_Host | Update Active Record for ‘VM_Host’ | in | Number |
VMHost_table | VMHost_table | Update Active Record for ‘VM_Host’ | in | SQL:Table |
VMHost_ReadResult | VMHost_ReadResult | Update Active Record for ‘VM_Host’ | in | SQL:ActiveRecord |
UpdateResult_VM_Host | UpdateResult_VM_Host | Update Active Record for ‘VM_Host’ | Out | Number |
Here is the script which we need in this module:
// we need the original values to load the record from the DB var NewArray = new Array(V_ID,VMUUID,ClusterfromDB,HostfromDB,RPfromDB,FolderfromDB) // we search for the record in the DB with the data from there VMHost_ReadResult = System.getModule("com.vmware.library.sql").findUniqueRecord(VMHost_table,NewArray); var columns = { VMID : V_ID, VMUUID : VMUUID, Cluster : clusterName, Host : runningHostName, ResourcePool : resourcePoolName, Folder : folderName }; UpdateResult_VM_Host = VMHost_table.updateRecord(VMHost_ReadResult, columns); System.log("Update DB with new host information")
After we have finished our mappings, we can connect the different workflows together. Also here it is the same schema as before. We connect the “GetVMfromHost_Info” to the decision “VM_Host_Change” from there we connect the false path to the “Scriptable Task” above and the true Path to “Update active record from ‘VM_Host”. From there we connect to also to the Scriptable task.
Now, I think everybody has an understanding from the method which is used here, so I will only provide the variables and the scripts for the last elements.
I call the next scriptable task “GetVMfromVM_Network”. Here are the required in- and outputs and the script:
Local Parameter | Variable Name | Module | Direction | Type |
V_ID | V_ID | GetVMInfofromVM_Network | in | string |
VMNetwork_table | VMNetwork_table | GetVMInfofromVM_Network | in | SQL:Table |
VMUUID | VMUUID | GetVMInfofromVM_Network | in | String |
VMInfofromDB | VMInfofromDB | GetVMInfofromVM_Network | in | SQL:ActiveRecord |
ipAddresses | ipAddresses | GetVMInfofromVM_Network | in | Array/string |
networks | networks | GetVMInfofromVM_Network | in | Array/string |
IPfromDB | IPfromDB | GetVMInfofromVM_Network | out | String |
NetworksfromDB | NetworksfromDB | GetVMInfofromVM_Network | out | String |
VM_Network_Change | VM_Network_Change | GetVMInfofromVM_Network | out | boolean |
IpAddressToString | IpAddressToString | GetVMInfofromVM_Network | out | string |
NetworksToString | NetworksToString | GetVMInfofromVM_Network | out | string |
// ------------------------------------------------------------- // we search for the Data of the virtual Machine with the Name and the UUID. First we define the search columns var columns = { VMID : V_ID, VMUUID : VMUUID, }; // Get the Data from the Table and put them in a SQL Active Record VMInfofromDB = VMNetwork_table.readRecords(columns); // The data from the SQL Record is a "String" with is sepearted with ",". We have to Split the String in Single Files..... // First, we put the String into a temporally Variable. var SplitConfigArraytoStringIP = VMInfofromDB.toString(); // In the Array, we search for the Keyword "IPAddress" var IPSearch = SplitConfigArraytoStringIP.search("IPAddress"); // The above defined search give us the Starting Position of our Keyword. We want the blank value, so we have to split // on Position 10 after the Start Position var IPStart = IPSearch + 10; // Here we split at the beginning of the Value with the rest of the string var IPStringTemp = SplitConfigArraytoStringIP.slice(IPStart); // We split on the first "," followed from a space. That's our value End. That's different then before because // the vm can have more than one ip which is separated thru a "," var IPStringEnd = IPStringTemp.search(/\s?,\s/); // Here we take the start and the end we figured out before and save the value into the Variable IPfromDB = IPStringTemp.slice(0, IPStringEnd); // The data from the SQL Record is a "String" with is sepearted with ",". We have to Split the String in Single Files..... // First, we put the String into a temporally Variable. var SplitConfigArraytoStringNet = VMInfofromDB.toString(); // In the Array, we search for the Keyword var NetSearch = SplitConfigArraytoStringNet.search("Network"); // The above defined search give us the Starting Position of our Keyword. We want the blank value, so we have to split // on Position 8 after the Start Position var NetStart = NetSearch + 8; // Here we split at the beginning of the Value with the rest of the string var NetStringTemp = SplitConfigArraytoStringNet.slice(NetStart); // We split on the first "," folowed from a space. That's our value End. That's different then before because // the vm can have more than one network which is separated thru a "," var NetStringEnd = NetStringTemp.search(/\s?,\s/); // Here we take the start and the end we figured out before and save the value into the Variable NetworksfromDB = NetStringTemp.slice(0, NetStringEnd); //----------------------------------------------------------------------------------------------------------------- // After we have our "configuration" Values, we have to check if there is a difference between the VM Data and // the data stored in the DB. // Catch empty Network and IpAddresses and set a placeholder text if ((ipAddresses == null) || (ipAddresses == "")) { IpAddressToString = "No IP adress found" } else { IpAddressToString = ipAddresses.toString() }; if ((networks== null) || (networks == "" )){ NetworksToString = "No networks found" } else { NetworksToString =networks.toString() }; if ((IPfromDB != IpAddressToString) || (NetworksfromDB != NetworksToString)){ // When there is a difference, we set the Variable to true VM_Network_Change = true;} else { // When there is no difference, we set the Variable to false VM_Network_Change = false;}
When you have a deeper look at the script, you will see that there is a change between this script and the two scripts before. Here we have (as by the insert into the DB) to convert our API Network information into a string! You will see the same conversation in the datastore script. Next we work with the Decision above. I call it “VM_Network_Change” and set the Value “VM_network_change” to true. Here is the table with the Variables:
Local Parameter | Variable Name | Module | Direction | Type |
VM_Network_Change | VM_Network_Change | VM_Network_Change | in | boolean |
Our last part for this three pair configuration is the “Scriptable task”. I call it “Update active record for ‘VM_Network”. We use the following in- and outputs:
Local Parameter | Variable Name | Module | Direction | Type |
V_ID | V_ID | Update active record for ‘VM_Network | in | String |
VMUUID | VMUUID | Update active record for ‘VM_Network | in | String |
NetworksToString | NetworksToString | Update active record for ‘VM_Network | in | String |
IpAddressToString | IpAddressToString | Update active record for ‘VM_Network | in | String |
IPfromDB | IPfromDB | Update active record for ‘VM_Network | in | String |
NetworksfromDB | NetworksfromDB | Update active record for ‘VM_Network | in | String |
VMNetwork_table | VMNetwork_table | Update active record for ‘VM_Network | in | SQL:Table |
VMNetworkRead_result | VMNetworkRead_result | Update active record for ‘VM_Network | in | SQL:ActiceRecord |
UpdateResult_VM_Network | UpdateResult_VM_Network | Update active record for ‘VM_Network | Out | Number |
And here is the script:
// We must catch "null" values and change them to "" // we do this for IPfromDB and NetworksfromDB // we need the original values to load the record from the DB if (IPfromDB == "null"){ IPfromDB = "";} if (NetworksfromDB == "null"){ NetworksfromDB = "";} var NewArray = new Array(V_ID,VMUUID,NetworksfromDB,IPfromDB) // we search for the record in the DB with the data from there VMNetworkRead_result = System.getModule("com.vmware.library.sql").findUniqueRecord(VMNetwork_table,NewArray); var columns = { VMID : V_ID, VMUUID : VMUUID, Network : NetworksToString, IPAddress : IpAddressToString }; UpdateResult_VM_Network = VMNetwork_table.updateRecord(VMNetworkRead_result, columns); System.log("Update DB with new network Information")
Now we can make our connections. Just follow the logic witch was used before. It is the same here…
Now let’s configure the last three pair of Workflows. We start with the scriptable task. I name it “GetVMfromVM_Datastore” and here are the used variables:
Local Parameter | Variable Name | Module | Direction | Type |
V_ID | V_ID | GetVMInfofromVM_Datastore | in | string |
VMDatastore_table | VMDatastore_table | GetVMInfofromVM_Datastore | in | SQL:Table |
VMUUID | VMUUID | GetVMInfofromVM_Datastore | in | String |
VMInfofromDB | VMInfofromDB | GetVMInfofromVM_Datastore | in | SQL:ActiveRecord |
datastoresName | datastoresName | GetVMInfofromVM_Datastore | in | Array/string |
diskSizes | diskSizes | GetVMInfofromVM_Datastore | in | Array/Number |
DatastorefromDB | DatastorefromDB | GetVMInfofromVM_Datastore | out | String |
DiskfromDB | DiskfromDB | GetVMInfofromVM_Datastore | out | String |
VM_Datastore_Change | VM_Datastore_Change | GetVMInfofromVM_Datastore | out | boolean |
DiskSizetoString | DiskSizetoString | GetVMInfofromVM_Datastore | out | String |
DatastoreNamestoString | DatastoreNamestoString | GetVMInfofromVM_Datastore | out | String |
And here is the required script:
// ------------------------------------------------------------- // we search for the Data of the virtual Machine with the Name and the UUID. First we define the search columns var columns = { VMID : V_ID, VMUUID : VMUUID, }; // Get the Data from the Table and put them in a SQL Active Record VMInfofromDB = VMDatastore_table.readRecords(columns); // The data from the SQL Record is a "String" with is sepearted with ",". We have to Split the String in Single Files..... // First, we put the String into a temporally Variable. var SplitConfigArraytoStringDisk = VMInfofromDB.toString(); // In the Array, we search for the Keyword var DiskSearch = SplitConfigArraytoStringDisk.search("DiskSize"); // The above defined search give us the Starting Position of our Keyword. We want the blank value, so we have to split // on Position 9 after the Start Position var DiskStart = DiskSearch + 9; // Here we split at the beginning of the Value with the rest of the string var DiskStringTemp = SplitConfigArraytoStringDisk.slice(DiskStart); // We split on the first "," folowed from a space. That's our value End. That's different then before because // the vm can have more than one ip which is separated thru a "," var DiskStringEnd = DiskStringTemp.search(/\s?,\s/); // Here we take the start and the end we figured out before and save the value into the Variable DiskfromDB = DiskStringTemp.slice(0, DiskStringEnd); // The data from the SQL Record is a "String" with is sepearted with ",". We have to Split the String in Single Files..... // First, we put the String into a temporally Variable. var SplitConfigArraytoStringData = VMInfofromDB.toString(); // In the Array, we search for the Keyword var DataSearch = SplitConfigArraytoStringData.search("Datastore"); // The above defined search give us the Starting Position of our Keyword. We want the blank value, so we have to split // on Position 10 after the Start Position var DataStart = DataSearch + 10; // Here we split at the beginning of the Value with the rest of the string var DataStringTemp = SplitConfigArraytoStringData.slice(DataStart); // We split on the first "}". That's our value End var DataStringEnd = DataStringTemp.search("}"); // Here we take the start and the end we figured out before and save the value into the Variable DatastorefromDB = DataStringTemp.slice(0, DataStringEnd); //----------------------------------------------------------------------------------------------------------------- // After we have our "configuration" Values, we have to check if there is a difference between the VM Data and // the data stored in the DB. // Catch empty disksizes and datastoreName and replace with a string if ((diskSizes == null) || (diskSizes == "")){ DiskSizeToString = "Could not read Disk Size" } else { DiskSizeToString = diskSizes.toString(); }; if ((datastoresName == null) || (datastoresName = "")) { DatastoreNamesToString = "Could not read Datastore Name" } else { DatastoreNamesToString = datastoresName.toString(); }; if ((DiskfromDB != DiskSizeToString) || (DatastorefromDB != DatastoreNamesToString)){ // When there is a difference, we set the Variable to true VM_Datastore_Change = true;} else { // When there is no difference, we set the Variable to false VM_Datastore_Change = false;}
Next we change the name for the decision to “VM_Datastore_Change”. As input we need:
Local Parameter | Variable Name | Module | Direction | Type |
VM_Datastore_Change | VM_Datastore_Change | VM_Datastore_Change | in | boolean |
Also here we set the Value VM_Datastore_Change to “true”.
Our last configuration must be done on the “Scriptable task”. I call it “Update active record for ‘VM_Datastore’”. Here we need the in- and outputs:
Local Parameter | Variable Name | Module | Direction | Type |
V_ID | V_ID | Update active record for ‘VM_Datastore’ | in | String |
VMUUID | VMUUID | Update active record for ‘VM_Datastore’ | in | String |
DiskSizetoString | DiskSizetoString | Update active record for ‘VM_Datastore’ | in | String |
DatastoreNamesToString | DatastoreNamesToString | Update active record for ‘VM_Datastore’ | in | String |
DiskfromDB | DiskfromDB | Update active record for ‘VM_Datastore’ | in | String |
DatastorefromDB | DatastorefromDB | Update active record for ‘VM_Datastore’ | in | String |
VMDatastore_table | VMDatastore_table | Update active record for ‘VM_Datastore’ | in | SQL:Table |
VMDatastoreRead_result | VMDatastoreRead_result | Update active record for ‘VM_Datastore’ | in | SQL:Active Record |
UpdateResult_VM_Datastore | UpdateResult_VM_Datastore | Update active record for ‘VM_Datastore’ | out | Number |
And this script:
// We must catch "null" values and change them to "" // we do this for DiskfromDB and DatastorefromDB // we need the original values to load the record from the DB if (DiskfromDB == "null"){ DiskfromDB = "";} if (DatastorefromDB == "null"){ DatastorefromDB = "";} // we search for the record in the DB with the data from there var NewArray = new Array(V_ID,VMUUID,DiskfromDB,DatastorefromDB) VMDatastoreRead_result = System.getModule("com.vmware.library.sql").findUniqueRecord(VMDatastore_table,NewArray); // Now we start to update the record with the new data var columns = { VMID : V_ID, VMUUID : VMUUID, DiskSize : DiskSizeToString, Datastore : DatastoreNamesToString }; UpdateResult_VM_Datastore = VMDatastore_table.updateRecord(VMDatastoreRead_result, columns); System.log("Update DB with new Storage Information")
At least we have to make our last connections. We start from “GetVMfromVM_Datastore” and go to the “VM_Datastore_Change”. From there we go with the false (the red) line to “NumberofVMs”. With the true (the green) line we go to “Update active record for ‘VM_Datastore’”. From there we connect to “NumberofVMs”.
After we have finished our configuration, let’s validate the workflow
And start….
If everything is fine, your DB will be updated with the last information and configuration changes of our virtual machines…..
That’s all for Part6…..