Forum Discussion
Adding actions to iControlREST transaction
I followed the steps in Chapter 5 of the iControl REST User guide but am unable to get any actions added to a transaction.
The step in "Create a transaction" sub-section that adds a create pool action to the transaction does not work. The text indicates a POST to /mgmt/tm/transaction with create pool JSON but return code is a HTTP 400 using the following curl commands: curl -u xx:xx -k -H "Content-Type: application/json" -X POST https://localhost/mgmt/tm/transaction -d {} curl -u xx:xx -k -H "Content-Type: application/json" -H "X-F5-REST-Coordination-ID: 1411760620" -o C:\Temp\Temp.json -X POST https://localhost:443/mgmt/tm/transaction -d "{\"name\":\"TEST.POOL\",\"partition\":\"webprod\"}"
Response JSON:
{
"code" : 400,
"message" : "A transaction id 1411760620 for the user has already created.",
"errorStack" : []
}
I thought this might be a typo in the guide so I changed the second curl command use /mgmt/tm/ltm/pool: curl -u xx:xx -k -H "Content-Type: application/json" -H "X-F5-REST-Coordination-ID: 1411760620" -o C:\Temp\Temp.json -X POST https://localhost:443/mgmt/tm/ltm/pool -d "{\"name\":\"TEST.POOL\",\"partition\":\"webprod\"}"
The response JSON is a HTTP 200, but it returns the newly created pool details instead of the successfully added to transaction response indicated in the user guide. Also, the create pool command is executed immediately instead of when the transaction is committed. If I execute a command to rollback the transaction, the newly created pool is not removed.
Anyone have any luck getting transactions to work successfully through iControlREST? Also, does anyone know how to change the transaction timeout value through iControlREST?
Notes:
* CURL commands were executed using curl 7.34.1-DEV for Windows
* F5 is BIG-IP 11.5.1 Build 4.53.128 Engineering Hotfix HF4
* F5 device name and user/pwd altered for privacy
Regards,
Greg Bui
7 Replies
- Arnaud_Lemaire
Employee
on my side it is working, using 11.6 here is the workflow
1) transaction creation : POST /mgmt/tm/transaction response :
{ "transId": 1411771265430600, "state": "STARTED", "timeoutSeconds": 30, "kind": "tm:transactionstate", "selfLink": "https://localhost/mgmt/tm/transaction/1411771265430600?ver=11.6.0" }2) adding a command to transaction POST /mgmt/tm/ltm/pool
Header : X-F5-REST-Coordination-Id: 1411771265430600
Payload:
{ "name":"transac-pool1", "members": [ {"name":"192.168.25.32:80","description":"First pool for transactions"} ] }Response :
{ "method": "POST", "uri": "https://localhost/mgmt/tm/ltm/pool", "body": { "name": "transac-pool1", "members": [ { "name": "192.168.25.32:80", "description": "First pool for transactions" }] }, "evalOrder": 1, "commandId": 1, "kind": "tm:transaction:commandsstate", "selfLink": "https://localhost/mgmt/tm/transaction/1411771265430600/commands/1?ver=11.6.0" }i received a 200 OK but if you check the response code is slightly different from a traditional REST call.
3) second call for another pool is doing the same thing
4) having a look to the pending commands : GET /mgmt/tm/transaction/1411771265430600/commands
{ "kind": "tm:transaction:commandscollectionstate", "selfLink": "https://localhost/mgmt/tm/transaction/1411771265430600/commands?ver=11.6.0", "items": [ { "method": "POST", "uri": "https://localhost/mgmt/tm/ltm/pool", "body": { "name": "transac-pool1", "members": [ { "name": "192.168.25.32:80", "description": "First pool for transactions" }] }, "evalOrder": 1, "commandId": 1, "kind": "tm:transaction:commandsstate", "selfLink": "https://localhost/mgmt/tm/transaction/1411771265430600/commands/1?ver=11.6.0" }, { "method": "POST", "uri": "https://localhost/mgmt/tm/ltm/pool", "body": { "name": "transac-pool2", "members": [ { "name": "192.168.25.32:80", "description": "second pool for transactions" }] }, "evalOrder": 2, "commandId": 2, "kind": "tm:transaction:commandsstate", "selfLink": "https://localhost/mgmt/tm/transaction/1411771265430600/commands/2?ver=11.6.0" } ] }5) then submit transaction PATCH /mgmt/tm/transaction/1411771265430600
no header !
payload :
{ "state":"VALIDATING" }response:
{ "transId": 1411771265430600, "state": "COMPLETED", "timeoutSeconds": 30, "kind": "tm:transactionstate", "selfLink": "https://localhost/mgmt/tm/transaction/1411771265430600?ver=11.6.0" }Having a look to GUI, pool is created.
Regarding you test, the second POST request should be correct, you create a POST as you would do usually but only the header F5-REST-Coordination-Id differentiate it from a normal request.
- Lior_54855
Nimbostratus
Hi Arnaud, I have the same problem but I doing exactly as you explained.
This is the output of the ssldump of the transcations:
--------------------------------------------------------------- POST /mgmt/tm/transaction HTTP/1.1 Accept: */*; q=0.5, application/xml Accept-Encoding: gzip, deflate Content-Type: application/json Content-Length: 2 User-Agent: Ruby Authorization: Basic YWRtaW46YWRtaW4= Host: 192.168.212.172 --------------------------------------------------------------- HTTP/1.1 200 OK Date: 28 Dec 2015 12:44:05 UTC Server: com.f5.rest.common.RestRequestSender Set-Cookie: BIGIPAuthCookie=017EA784717D2DC416AFD90FB58842083DE1BD23; path=/; Secure; HttpOnly Set-Cookie: BIGIPAuthUsernameCookie=admin; path=/; Secure; HttpOnly X-Frame-Options: SAMEORIGIN Cache-Control: no-cache Content-Length: 162 Content-Type: application/json X-Content-Type-Options: nosniff X-XSS-Protection: 1; mode=block Content-Security-Policy: default-src 'self' https://sentinel.whitehatsec.com https://api.ctscloud.com https://key.ctscloud.com 'unsafe-inline' 'unsafe-eval' Strict-Transport-Security: max-age=16070400; includeSubDomains --------------------------------------------------------------- application_data ------------------------------------------------------------ {"transId":1451306645,"state":"STARTED","timeoutSeconds":30,"kind":"tm:transactionstate","selfLink":"https://localhost/mgmt/tm/transaction/1451306645?ver=11.5.1"} --------------------------------------------------------------- POST /mgmt/tm/ltm/pool HTTP/1.1 Accept: */*; q=0.5, application/xml Accept-Encoding: gzip, deflate Content-Type: application/json X-F5-Rest-Coordination-Id: 1451306645 Content-Length: 87 User-Agent: Ruby Authorization: Basic YWRtaW46YWRtaW4= Host: 192.168.212.172 --------------------------------------------------------------- application_data --------------------------------------------------------------- {"name":"www.test1.co.il_HTTP_Pool","partition":"Main","monitor":"Generic_http_lbtest"} --------------------------------------------------------------- HTTP/1.1 200 OK Date: 28 Dec 2015 12:56:16 UTC Server: com.f5.rest.common.RestRequestSender Set-Cookie: BIGIPAuthCookie=017EA784717D2DC416AFD90FB58842083DE1BD23; path=/; Secure; HttpOnly Set-Cookie: BIGIPAuthUsernameCookie=admin; path=/; Secure; HttpOnly X-Frame-Options: SAMEORIGIN Cache-Control: no-cache Content-Length: 868 Content-Type: application/json X-Content-Type-Options: nosniff X-XSS-Protection: 1; mode=block Content-Security-Policy: default-src 'self' https://sentinel.whitehatsec.com https://api.ctscloud.com https://key.ctscloud.com 'unsafe-inline' 'unsafe-eval' Strict-Transport-Security: max-age=16070400; includeSubDomains --------------------------------------------------------------- application_data --------------------------------------------------------------- {"kind":"tm:ltm:pool:poolstate","name":"www.test1.co.il_HTTP_Pool","partition":"Main","fullPath":"/Main/www.test1.co.il_HTTP_Pool","generation":34258,"selfLink":"https://localhost/mgmt/tm/ltm/pool/~Main~www.test1.co.il_HTTP_Pool?ver=11.5.1","allowNat":"yes","allowSnat":"yes","ignorePersistedWeight":"disabled","ipTosToClient":"pass-through","ipTosToServer":"pass-through","linkQosToClient":"pass-through","linkQosToServer":"pass-through","loadBalancingMode":"round-robin","minActiveMembers":0,"minUpMembers":0,"minUpMembersAction":"failover","minUpMembersChecking":"disabled","monitor":"/Common/Generic_http_lbtest ","queueDepthLimit":0,"queueOnConnectionLimit":"disabled","queueTimeLimit":0,"reselectTries":0,"slowRampTime":10,"membersReference":{"link":"https://localhost/mgmt/tm/ltm/pool/~Main~www.test1.co.il_HTTP_Pool/members?ver=11.5.1","isSubcollection":true}}And then the pool is created without the transaction commit. Any ideas?
Thanks
- Lior_54855
Nimbostratus
Hi,
The problem is that the ruby GEM net-http changed the header from:
X-F5-REST-Coordination-Id
to:
X-F5-Rest-Coordination-Id
- Ichnafi
Cirrostratus
My Problem:
I create successfully a transaction and added tasks to it (add a vlan and route-domain). When i check the commands list I get:
object(stdClass)[3] public 'kind' => string 'tm:transaction:commandscollectionstate' (length=38) public 'selfLink' => string 'https://localhost/mgmt/tm/transaction/1484740224001215/commands?ver=12.1.0' (length=74) public 'items' => array (size=2) 0 => object(stdClass)[4] public 'method' => string 'POST' (length=4) public 'uri' => string 'https://localhost/mgmt/tm/net/vlan' (length=34) public 'body' => object(stdClass)[5] public 'name' => string 'testvlan' (length=8) public 'tag' => string '627' (length=3) public 'interfaces' => array (size=1) 0 => object(stdClass)[6] ... public 'evalOrder' => int 1 public 'commandId' => int 1 public 'kind' => string 'tm:transaction:commandsstate' (length=28) public 'selfLink' => string 'https://localhost/mgmt/tm/transaction/1484740224001215/commands/1?ver=12.1.0' (length=76) 1 => object(stdClass)[7] public 'method' => string 'POST' (length=4) public 'uri' => string 'https://localhost/mgmt/tm/net/route-domain' (length=42) public 'body' => object(stdClass)[8] public 'name' => string 'testRD' (length=6) public 'id' => string '4533' (length=4) public 'vlans' => array (size=1) 0 => string '/Common/testvlan' (length=16) public 'evalOrder' => int 2 public 'commandId' => int 2 public 'kind' => string 'tm:transaction:commandsstate' (length=28) public 'selfLink' => string 'https://localhost/mgmt/tm/transaction/1484740224001215/commands/2?ver=12.1.0' (length=76)But when I try to commit the transaction, i only get a HTTP 415 and the transaction state stays at "UPDATING".
object(stdClass)[3] public 'transId' => string '1484740224001215' (length=16) public 'state' => string 'UPDATING' (length=8) public 'timeoutSeconds' => int 120 public 'asyncExecution' => boolean false public 'validateOnly' => boolean false public 'executionTimeout' => int 300 public 'executionTime' => int 0 public 'failureReason' => string '' (length=0) public 'kind' => string 'tm:transactionstate' (length=19) public 'selfLink' => string 'https://localhost/mgmt/tm/transaction/1484740224001215?ver=12.1.0' (length=65)My php/curl transaction function looks like this:
public function executeTransaction($transId) { $ch = curl_init($this->BASE_URL . "/transaction/" . $transId); $encoded_data = '{ "state":"VALIDATING" }'; curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "PATCH"); curl_setopt($ch, CURLOPT_FAILONERROR, true); curl_setopt($ch, CURLOPT_POSTFIELDS, $encoded_data); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_USERPWD, "$this->username:$this->password"); $result = curl_exec($ch); $this->code = curl_getinfo($ch, CURLINFO_HTTP_CODE); return json_decode($result, false, 512, JSON_BIGINT_AS_STRING); }Does anyone has a hint for me?
- Ichnafi_177360
Nimbostratus
My Problem:
I create successfully a transaction and added tasks to it (add a vlan and route-domain). When i check the commands list I get:
object(stdClass)[3] public 'kind' => string 'tm:transaction:commandscollectionstate' (length=38) public 'selfLink' => string 'https://localhost/mgmt/tm/transaction/1484740224001215/commands?ver=12.1.0' (length=74) public 'items' => array (size=2) 0 => object(stdClass)[4] public 'method' => string 'POST' (length=4) public 'uri' => string 'https://localhost/mgmt/tm/net/vlan' (length=34) public 'body' => object(stdClass)[5] public 'name' => string 'testvlan' (length=8) public 'tag' => string '627' (length=3) public 'interfaces' => array (size=1) 0 => object(stdClass)[6] ... public 'evalOrder' => int 1 public 'commandId' => int 1 public 'kind' => string 'tm:transaction:commandsstate' (length=28) public 'selfLink' => string 'https://localhost/mgmt/tm/transaction/1484740224001215/commands/1?ver=12.1.0' (length=76) 1 => object(stdClass)[7] public 'method' => string 'POST' (length=4) public 'uri' => string 'https://localhost/mgmt/tm/net/route-domain' (length=42) public 'body' => object(stdClass)[8] public 'name' => string 'testRD' (length=6) public 'id' => string '4533' (length=4) public 'vlans' => array (size=1) 0 => string '/Common/testvlan' (length=16) public 'evalOrder' => int 2 public 'commandId' => int 2 public 'kind' => string 'tm:transaction:commandsstate' (length=28) public 'selfLink' => string 'https://localhost/mgmt/tm/transaction/1484740224001215/commands/2?ver=12.1.0' (length=76)But when I try to commit the transaction, i only get a HTTP 415 and the transaction state stays at "UPDATING".
object(stdClass)[3] public 'transId' => string '1484740224001215' (length=16) public 'state' => string 'UPDATING' (length=8) public 'timeoutSeconds' => int 120 public 'asyncExecution' => boolean false public 'validateOnly' => boolean false public 'executionTimeout' => int 300 public 'executionTime' => int 0 public 'failureReason' => string '' (length=0) public 'kind' => string 'tm:transactionstate' (length=19) public 'selfLink' => string 'https://localhost/mgmt/tm/transaction/1484740224001215?ver=12.1.0' (length=65)My php/curl transaction function looks like this:
public function executeTransaction($transId) { $ch = curl_init($this->BASE_URL . "/transaction/" . $transId); $encoded_data = '{ "state":"VALIDATING" }'; curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "PATCH"); curl_setopt($ch, CURLOPT_FAILONERROR, true); curl_setopt($ch, CURLOPT_POSTFIELDS, $encoded_data); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_USERPWD, "$this->username:$this->password"); $result = curl_exec($ch); $this->code = curl_getinfo($ch, CURLINFO_HTTP_CODE); return json_decode($result, false, 512, JSON_BIGINT_AS_STRING); }Does anyone has a hint for me?
- Ichnafi_177360
Nimbostratus
To Answer my own Question:
You have to specify a header with Content-Type (and optional Content-Length) BUT you have to omit the 'X-F5-REST-Coordination-Id:' in it. So I added the follwing curl-option to my function. It works now.
curl_setopt($ch, CURLOPT_HTTPHEADER, array( 'Content-Type: application/json', 'Content-Length: ' . strlen($encoded_data)) ); - Ichnafi
Cirrostratus
To Answer my own Question:
You have to specify a header with Content-Type (and optional Content-Length) BUT you have to omit the 'X-F5-REST-Coordination-Id:' in it. So I added the follwing curl-option to my function. It works now.
curl_setopt($ch, CURLOPT_HTTPHEADER, array( 'Content-Type: application/json', 'Content-Length: ' . strlen($encoded_data)) );
Help guide the future of your DevCentral Community!
What tools do you use to collaborate? (1min - anonymous)Recent Discussions
Related Content
* Getting Started on DevCentral
* Community Guidelines
* Community Terms of Use / EULA
* Community Ranking Explained
* Community Resources
* Contact the DevCentral Team
* Update MFA on account.f5.com