This cookbook lists selected ready-to-use iControl REST curl commands for virtual-server related resources. Each receipe consists of the curl command, it's tmsh equivallent, and sample output (default hidden: toggle "Expand to see sample output" (may not work on some browsers))

In this cookbook, the following curl options are used.

Option Meaning
-s Suppress progress meter. Handy when you want to pipe the output.
-k Allows "insecure" SSL connections.
-u Specify user ID and password. For the start, you should use the "admin" account that you normally use to access the Configuration Utility. When you specify the password at the same time, concatenate with ":". e.g., admin:admin.
-X <method> Specify the HTTP method. When omitted, the default is GET. In the REST framework, POST means create (tmsh create), PATCH means overwriting the existing resource with the data sent (tmsh modify), and PATCH is for merging (ditto).
-H <Header> Specify the request header. When you send (POST, PATCH, PUT) data, you need to tell the server that the data is in JSON format. i.e., -H "Content-Type: application/json.
-d 'data' The JSON data to send. Note that you need to quote the entire json blob, and each "name":"value" pairs must be quoted. When you have nested quotes, make sure you escape (\) them.

Get all configuration information of the virtual <vs>

tmsh list ltm <vs>

curl -sku admin:admin https://<host>/mgmt/tm/ltm/virtual/<vs>
Expand to see sample output (may not work on some browsers)
{ kind: 'tm:ltm:virtual:virtualstate',
  name: 'vs',
  fullPath: 'vs',
  generation: 1109,
  selfLink: 'https://localhost/mgmt/tm/ltm/virtual/vs?ver=12.1.0',
  addressStatus: 'yes',
  autoLasthop: 'default',
  cmpEnabled: 'yes',
  connectionLimit: 0,
  description: 'TestData',
  destination: '/Common/192.168.184.226:80',
  enabled: true,
  gtmScore: 0,
  ipProtocol: 'tcp',
  mask: '255.255.255.255',
  mirror: 'disabled',
  mobileAppTunnel: 'disabled',
  nat64: 'disabled',
  pool: '/Common/vs-pool',
  poolReference: { link: 'https://localhost/mgmt/tm/ltm/pool/~Common~vs-pool?ver=12.1.0' },
  rateLimit: 'disabled',
  rateLimitDstMask: 0,
  rateLimitMode: 'object',
  rateLimitSrcMask: 0,
  serviceDownImmediateAction: 'none',
  source: '0.0.0.0/0',
  sourceAddressTranslation: { type: 'automap' },
  sourcePort: 'preserve',
  synCookieStatus: 'not-activated',
  translateAddress: 'enabled',
  translatePort: 'enabled',
  vlansDisabled: true,
  vsIndex: 4,
  rules: [ '/Common/irule' ],
  rulesReference: [ { link: 'https://localhost/mgmt/tm/ltm/rule/~Common~iRuleTest?ver=12.1.0' } ],
  policiesReference: {
    link: 'https://localhost/mgmt/tm/ltm/virtual/~Common~vs/policies?ver=12.1.0',
    isSubcollection: true
  },
  profilesReference: {
    link: 'https://localhost/mgmt/tm/ltm/virtual/~Common~vs/profiles?ver=12.1.0',
     isSubcollection: true
  }
}

Get only specfic field of the virtual <vs>

The naming convension for the parameters is slightly different from the ones on tmsh, so look for the familiar names in the GET response above. The example below queris the Default Pool (pool).

tmsh list ltm <vs> pool

curl -sku admin:admin https://<host>/mgmt/tm/ltm/virtual/<vs>?options=pool
Expand to see sample output (may not work on some browsers)
{ kind: 'tm:ltm:virtual:virtualstate',
  name: 'vs',
  fullPath: 'vs',
  generation: 1,
  selfLink: 'https://localhost/mgmt/tm/ltm/virtual/vs?options=pool&ver=12.1.1',
  pool: '/Common/vs-pool',
  poolReference: {
    link: 'https://localhost/mgmt/tm/ltm/pool/~Common~vs-pool?ver=12.1.1'
  }
}

Get stats of the virtual <vs>

tmsh show ltm <vs>

curl -sku admin:admin https://<host>/mgmt/tm/ltm/virtual/<vs>/stats
Expand to see sample output (may not work on some browsers)
{ kind: 'tm:ltm:virtual:virtualstats',
  generation: 1109,
  selfLink: 'https://localhost/mgmt/tm/ltm/virtual/vs/stats?ver=12.1.0',
  entries:
   { 'https://localhost/mgmt/tm/ltm/virtual/vs/~Common~vs/stats':
      { nestedStats:
         { kind: 'tm:ltm:virtual:virtualstats',
           selfLink: 'https://localhost/mgmt/tm/ltm/virtual/vs/~Common~vs/stats?ver=12.1.0',
           entries:
            { 'clientside.bitsIn': { value: 12880 },
              'clientside.bitsOut': { value: 34592 },
              'clientside.curConns': { value: 0 },
              'clientside.evictedConns': { value: 0 },
              'clientside.maxConns': { value: 2 },
              'clientside.pktsIn': { value: 26 },
              'clientside.pktsOut': { value: 26 },
              'clientside.slowKilled': { value: 0 },
              'clientside.totConns': { value: 6 },
              cmpEnableMode: { description: 'all-cpus' },
              cmpEnabled: { description: 'enabled' },
              csMaxConnDur: { value: 37 },
              csMeanConnDur: { value: 29 },
              csMinConnDur: { value: 17 },
              destination: { description: '192.168.184.226:80' },
              'ephemeral.bitsIn': { value: 0 },
              'ephemeral.bitsOut': { value: 0 },
              'ephemeral.curConns': { value: 0 },
              'ephemeral.evictedConns': { value: 0 },
              'ephemeral.maxConns': { value: 0 },
              'ephemeral.pktsIn': { value: 0 },
              'ephemeral.pktsOut': { value: 0 },
              'ephemeral.slowKilled': { value: 0 },
              'ephemeral.totConns': { value: 0 },
              fiveMinAvgUsageRatio: { value: 0 },
              fiveSecAvgUsageRatio: { value: 0 },
              tmName: { description: '/Common/vs' },
              oneMinAvgUsageRatio: { value: 0 },
              'status.availabilityState': { description: 'available' },
              'status.enabledState': { description: 'enabled' },
              'status.statusReason': { description: 'The virtual server is available' },
              syncookieStatus: { description: 'not-activated' },
              'syncookie.accepts': { value: 0 },
              'syncookie.hwAccepts': { value: 0 },
              'syncookie.hwSyncookies': { value: 0 },
              'syncookie.hwsyncookieInstance': { value: 0 },
              'syncookie.rejects': { value: 0 },
              'syncookie.swsyncookieInstance': { value: 0 },
              'syncookie.syncacheCurr': { value: 0 },
              'syncookie.syncacheOver': { value: 0 },
              'syncookie.syncookies': { value: 0 },
              totRequests: { value: 4 }
            }
         }
      }
   }
}

Change one of the configuration options of the virtual <vs>

The command below changes the Description field of the virtual ("description" in tmsh and iControl REST).

tmsh modify ltm virtual <vs> description "Hello World!"

curl -sku admin:admin -X PATCH -H "Content-Type: application/json" \
  -d '{"description": "Hello World!"}' \
  https://<host>/mgmt/tm/ltm/<vs>
Expand to see sample output (may not work on some browsers)
{ kind: 'tm:ltm:virtual:virtualstate',
  name: 'vs',
  ... 
  description: 'Hello World!',       <==== Changed.
  ...
}

Disable the virtual <vs>

The command syntax is same as above: To disable/enable, you change the parameter "enabled". Note that the boolean type true/false does not require quotations.

tmsh modify ltm virtual <vs> disabled

curl -sku admin:admin -X PATCH -H "Content-Type: application/json" \
  -d '{"enabled": false}' \
  https://<host>/mgmt/tm/ltm/<vs>
Expand to see sample output (may not work on some browsers)
{ kind: 'tm:ltm:virtual:virtualstate',
  name: 'vs',
  fullPath: 'vs',
  ...
  enabled: false,  <== Changed
  ...
}

Add another iRule to <vs>

Even if the iRule /Common/test1 is already attached to <vs>, you need to explicitly specify both the additional and existing ones. It is assumed that the additional /Common/test2 already exists on the system herein.

tmsh modify ltm virtual <vs> rules {test1 test2}

curl -sku admin:admin -X PATCH -H "Content-Type: application/json" \
  -d '{"rules": ["/Common/test1", "/Common/test2"] }' \
  https://<host>/mgmt/tm/ltm/virtual/<vs>
Expand to see sample output (may not work on some browsers)
{ kind: 'tm:ltm:virtual:virtualstate',
  name: 'vs',
  fullPath: 'vs',
  ...
  rules: [ '/Common/test1', '/Common/test2' ],  <== Changed
  rulesReference:
   [ { link: 'https://localhost/mgmt/tm/ltm/rule/~Common~test1?ver=12.1.1' },
     { link: 'https://localhost/mgmt/tm/ltm/rule/~Common~test2?ver=12.1.1' } ],
  ...
}

Create a new virtual <vs>

You can create a skelton virtual without any parameters: they are all set to default - You can PATCH the parameters separately later. Most parameters are independent of each other except Destination Address/Mask and Port: they must be specified in a single request as below.

tmsh create ltm virtual <vs> destination <ip:port> mask <ip>

curl -sku admin:admin -X POST -H "Content-Type: application/json" \
  -d '{"name": "vs", "destination":"192.168.184.230:80", "mask":"255.255.255.255"}' \
  https://<host>/mgmt/tm/ltm/virtual
Expand to see sample output (may not work on some browsers)
{ kind: 'tm:ltm:virtual:virtualstate',
  name: 'vs',
  partition: 'Common',
  fullPath: '/Common/vs',
  ...
  destination: '/Common/192.168.184.230:80',  <== Created
  ...
  mask: '255.255.255.255',                    <== Created
  ...
}

Delete a virtual <vs>

tmsh delete ltm virtual <vs>

curl -sku admin:admin -X DELETE https://192.168.226.55/mgmt/tm/ltm/virtual/<vs>
Expand to see sample output (may not work on some browsers)
No output (just 200 OK and no response body)

References