F5 Dynamic Types Plugin – Ready to Extend Part 1

The concept of Dynamic Types is that you don’t need to be “Programmer” or “Software Engineer” in order to develop your own plugin, everything is based on JavaScript and/or existing workflows.

When you export a plugin configuration using Dynamic Types Plugin Generator, you basically create an open-source package that everyone can reuse or even update.

In the next couple of posts, I’ll show you how to extend the plugin in order to answer you environment needs.

Create New Types

In order to create new types you can use vCOTeam guide and follow this demo that I did for this plugin:

If you think that I need to add new types to the plugin, please share your thoughts and I’ll try to add those to the next release.

Create New Objects

Most of theCreate object” workflows are structured in the same way, so let’s take a look in the “Create Pool” workflow:

Screenshot 2015-05-03 16.12.06

Four steps for this workflow:

  1. Setting the object “unique” attributes
  2. Building the JSON object for the REST call body
  3. Getting the RestHost object from the LTMHost object (this is needed only for the create process)
  4. Invoke the Create Object Method

The first step will be unique in each object that we’ll deal with, but the setContent and the Invoke Object Method will be used in each workflow.

Serialize lbMethod:

  1. lbMethod = loadbalance.toLowerCase();
  2. lbMethod = lbMethod.split(” “).join(“-“);


In LTM GUI you have predefined list of load balancing methods:

Screenshot 2015-05-03 16.25.56

When using the API we can’t use the explicit method name – everything is lower case and no space or brackets, only “-” (Round Robin => round-robin, Ratio (node) => ratio-node).

So “Serialize lbMethod” does it for you, so in case I didn’t add the method that you’re looking for, just edit the configuration element “lbMethods” and add your method (with “(” or “)”:

Screenshot 2015-05-03 16.34.15

Get Monitor Full Path:

  1. monitorName = “”;
  2. if (monitors != null) {
  3.     if (monitors.length > 1)
  4.     {
  5.         for (= 0 ; i < monitors.length ; i++)
  6.         {
  7.             if (i+1==monitors.length) {
  8.                 monitorName += monitors[i].fullPath;
  9.             }
  10.             else {
  11.                 monitorName += monitors[i].fullPath + ” and “;
  12.             }
  13.         }
  14.     }
  15.     if (monitors.length == 1) {
  16.         monitorName = monitors[0].fullPath;
  17.     }
  18. }


This element does two things: First, when creating pools, the pool monitor attribute needs the full path of the monitor object. Full path meaning the Partition of the object and the object name “/Common/myMonitor”. Second, more then one monitor can be use by single pool.

So, Get Monitor Full Path gets the Full Path of all monitors, and then create one line that aggregate all monitors – eventually you will get one line like this: “monitor”:”/Common/https and /Common/myMonitor”.


  1. object = { 
  2.   “name”: name,
  3.   “description”: description,
  4.   “loadBalancingMode”: lbMethod,
  5.   “monitor”: monitorName
  6. };
  7. content = JSON.stringify(object);


This element responsible on building the JSON object in the right structure. In this case “name” and “description” are both input from the user, but the lbMethod and monitorName are the output from “Serialize lbMethod” and “Get Monitor Full Path”

The JSON.stringify() method converts a JavaScript value to a JSON string, without it the REST body request will be invalid because the object is unknown for the API.


To be honest, you don’t need to use this action, Christophe already wrote an action (getRestHost) that extract the restHost object from any Dynamic Type object that was created by the Plugin Generator.

The reason that I built my own action, is that I’m developing “cluster mode” that will support LTM Cluster… 🙂 Stay tuned!

Create LTM Pool:

This worfklow is the predefined “Invoke a Create Object Method” from the plugin generator. You can read more about how to wrap this workflow in this guide. The only difference in my case, is that I’m using the “content” input parameter instead of passing multiple parameters.

Screenshot 2015-05-03 17.09.55

The reason that I decided to use the “content” input and not multiple parameters, is that in case you will need to add more input parameters to your workflows you don’t need to touch the plugin generator workflow. just add input parameter to the workflow and to the script in the “setContent” and that’s it!

How do you know what other parameter you can add? you can query you LTM by using POSTMAN.

  1. Create manually your object like you want it to be
  2. Query the object using POSTMAN
  3. Update the setContent and the workflow according to the new input
  4. DONE!

Here is an example of pool query:

  1. {
  2.     “kind”: “tm:ltm:pool:poolstate”,
  3.     “name”: “TestPool”,
  4.     “fullPath”: “TestPool”,
  5.     “generation”: 179,
  6.     “selfLink”: “https://localhost/mgmt/tm/ltm/pool/TestPool?ver=11.6.0”,
  7.     “allowNat”: “yes”,
  8.     “allowSnat”: “yes”,
  9.     “description”: “test”,
  10.     “ignorePersistedWeight”: “disabled”,
  11.     “ipTosToClient”: “pass-through”,
  12.     “ipTosToServer”: “pass-through”,
  13.     “linkQosToClient”: “pass-through”,
  14.     “linkQosToServer”: “pass-through”,
  15.     “loadBalancingMode”: “round-robin”,
  16.     “minActiveMembers”: 0,
  17.     “minUpMembers”: 0,
  18.     “minUpMembersAction”: “failover”,
  19.     “minUpMembersChecking”: “disabled”,
  20.     “monitor”: “/Common/http “,
  21.     “queueDepthLimit”: 0,
  22.     “queueOnConnectionLimit”: “disabled”,
  23.     “queueTimeLimit”: 0,
  24.     “reselectTries”: 0,
  25.     “serviceDownAction”: “none”,
  26.     “slowRampTime”: 10,
  27.     “membersReference”: {
  28.         “link”: “https://localhost/mgmt/tm/ltm/pool/~Common~TestPool/members?ver=11.6.0”,
  29.         “isSubcollection”: true
  30.     }
  31. }


In the current Create Pool workflow, I just taking care of the Name, Description, Monitor and the LoadBalancingMethod. But, as you can see, all other attributes got the default values.

The only thing we need to do, is just take the attribute that we want to change as part of the creation… I’ll add the minUpMembers. Now the setContent will be:

  1. object = { 
  2.   “name”: name,
  3.   “description”: description,
  4.   “loadBalancingMode”: lbMethod,
  5.   “minUpMembers”: minUpMembers,
  6.   “monitor”: monitorName
  7. };
  8. content = JSON.stringify(object);

and minUpMembers will be input parameter and with type “number”.

Screenshot 2015-05-03 17.33.35

Now you can add any attribute that you want!

Update Objects

Updating existing object it’s kind of the same story, but shorter. Let’s take a look how the “Add Member to Pool (VM) is built.

Screenshot 2015-05-03 17.36.07

In this case, only two steps are needed:

  1. Building the JSON object for the REST call body
  2. Invoke the Object Method


  1. object = { 
  2.       “name”: vm.name+“:”+memberPort,
  3.       “address”: vm.guest.ipAddress,
  4.       “ratio”: memberRatio
  5.     };
  6. poolName = pool.name;
  7. content = JSON.stringify(object);


Same as the create workflow, we build the JSON object.

But in this case, we also extracting the name of the pool, because in order to update an existing object the PUT call  URL will include the pool name, for example: https://ltm.corp.local/mgmt/tm/ltm/pool/TestPool.

Invoke an object method:

This is a predefined workflow from the plugin generator. In this case I’m also using the “content” input parameter instead of passing multiple parameters and also passing the pool name to param_0 that effect the URL like a mentioned above.

Screenshot 2015-05-03 18.13.22

You don’t need to get the restHost object when update/delete existing object, the invoke object method/invoke delete object method will extract the restHost from the object.


So that it for now, in the next post I’ll cover more about creating Monitors and Profiles.

Stay tuned!


One thought on “F5 Dynamic Types Plugin – Ready to Extend Part 1

  1. Pingback: F5 Dynamic Types Plugin – Ready to Extend Part 2 | VIRTUAL 'EM ALL!

Leave a Reply