cancel
Showing results for 
Search instead for 
Did you mean: 

iControl REST API Policy Rules

jjohnson
Nimbostratus
Nimbostratus

Having some trouble getting rules added to an LTM policy using iControl REST API and PowerShell. Currently I am able to get the policy into Draft status, and I can add a rule... but I am getting stuck in the formatting for the rule actions and conditions. Does anyone know how these are supposed to be formatted?

 

The only examples and guidance I have been able to find don't show how to add any actions to the rules.

 

https://clouddocs.f5.com/api/icontrol-rest/APIRef_tm_ltm_policy.html

rules array_structure optional read/write

 

https://devcentral.f5.com/s/articles/icontrol-rest-cookbook-ltm-policy-ltm-policy-33300

curl -sku admin:admin https://<host>/mgmt/tm/ltm/policy/~Common~Drafts~<TestPolicy>/rules \ -X POST -H "Content-type:application/json" \ -d '{"name":"<SampleRule>", "description":"sat1" }'

 

The above example shows how to create a rule and give it a description, but not how to add anything to it. Any help is appreciated.

 

Code I have used so far for creating the Draft and Rule:

 

$user = "admin" $pass = "admin" $url = "<my f5 url>" $header = @{"Authorization" = "Basic "+[System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes("$user"+":"+"$pass"));} $policy = "TEST_POLICY_AUTOMATION"   $DraftBody = @{     "createDraft" = $True }   $RulesBody = @{     "name" = "Test.API"     "description" = "I am a test" }   ### Create a draft from a policy that already exists   Invoke-RestMethod -Uri https://$url/mgmt/tm/ltm/policy/$Policy -Method PATCH -Headers $Header -Body (ConvertTo-Json $DraftBody) -ContentType "application/json"   ### Attempts at modifying/adding rules to the policy in draft ### Creating the rule with name Test.API and description "I am a test" works but have been unable to add actions   Invoke-RestMethod -Uri https://$url/mgmt/tm/ltm/policy/~Common~Drafts~$Policy/rules -Method POST -Headers $Header -Body (ConvertTo-Json $RulesBody) -ContentType 'application/json'

 

7 REPLIES 7

cjunior
Nacreous
Nacreous

Hello,

Far as I know you need to create a rule, then add actions and conditions on it.

e.g.

 

# Create a policy draft curl -kv -u admin:admin https://localhost/mgmt/tm/ltm/policy \ -X POST -H "Content-type:application/json" \ -d '{ "name": "/Common/Drafts/policy_vs_devcentral", "strategy": "first-match"}' | jq "."   # Add a rule curl -kv -u "admin:admin" https://localhost/mgmt/tm/ltm/policy/~Common~Drafts~policy_vs_devcentral/rules \ -X POST -H "Content-type:application/json" \ -d '{"name": "ruleTest" }' | jq "."   # Add conditions and actions to a rule curl -kv -u "admin:admin" -X PUT https://localhost/mgmt/tm/ltm/policy/~Common~Drafts~policy_vs_devcentral/rules/ruleTest \ -H "Content-type: application/json" \ -d @- << EOF | jq "." { "actions": [ { "name": "0", "request": true, "forward": true, "pool": "/Common/pool_test" } ], "conditions": [ { "name":"0", "request": true, "httpHost": true, "equals": true, "values": [ "www.mydomain.net" ] } ] } EOF

A tip to easy know all parameters for a certain rule, you create a manually example then retrieve that actions and conditions to understand what parameters you need to fill.

e.g.

I manually created a rule "ruleRedirect" to redirect traffic when host equals "www.test.net" and path equals "/" to a home page:

So, I get conditions and actions from that rule name:

curl -k -u "admin:admin" https://localhost/mgmt/tm/ltm/policy/~Common~Drafts~policy_vs_devcentral/rules/ruleRedirect/conditions |jq "."   { "kind": "tm:ltm:policy:rules:conditions:conditionscollectionstate", "selfLink": "https://localhost/mgmt/tm/ltm/policy/~Common~Drafts~policy_vs_devcentral/rules/ruleRedirect/conditions?ver=14.1.2.2", "items": [ { "kind": "tm:ltm:policy:rules:conditions:conditionsstate", "name": "0", "fullPath": "0", "generation": 2463, "selfLink": "https://localhost/mgmt/tm/ltm/policy/~Common~Drafts~policy_vs_devcentral/rules/ruleRedirect/conditions/0?ver=14.1.2.2", "all": true, "caseInsensitive": true, "equals": true, "external": true, "httpHost": true, "index": 0, "present": true, "remote": true, "request": true, "values": [ "www.test.net" ] }, { "kind": "tm:ltm:policy:rules:conditions:conditionsstate", "name": "1", "fullPath": "1", "generation": 2463, "selfLink": "https://localhost/mgmt/tm/ltm/policy/~Common~Drafts~policy_vs_devcentral/rules/ruleRedirect/conditions/1?ver=14.1.2.2", "all": true, "caseInsensitive": true, "equals": true, "external": true, "httpUri": true, "index": 0, "present": true, "remote": true, "request": true, "values": [ "/" ] } ] }curl -k -u "admin:admin" https://localhost/mgmt/tm/ltm/policy/~Common~Drafts~policy_vs_devcentral/rules/ruleRedirect/actions |jq "."   { "kind": "tm:ltm:policy:rules:actions:actionscollectionstate", "selfLink": "https://localhost/mgmt/tm/ltm/policy/~Common~Drafts~policy_vs_devcentral/rules/ruleRedirect/actions?ver=14.1.2.2", "items": [ { "kind": "tm:ltm:policy:rules:actions:actionsstate", "name": "0", "fullPath": "0", "generation": 2463, "selfLink": "https://localhost/mgmt/tm/ltm/policy/~Common~Drafts~policy_vs_devcentral/rules/ruleRedirect/actions/0?ver=14.1.2.2", "code": 0, "expirySecs": 0, "httpReply": true, "length": 0, "location": "https://www.test.net/home", "offset": 0, "port": 0, "redirect": true, "request": true, "status": 0, "timeout": 0, "vlanId": 0 } ] }

Now I know that to create a redirection rule this is the json body to push:

{ "conditions": [ { "name": "0", "request": true, "httpHost": true, "equals": true, "values": [ "www.test.net" ] }, { "name": "1", "request": true, "httpUri": true, "equals": true, "values": [ "/" ] } ], "actions": [ { "name": "0", "request": true, "httpReply": true, "redirect": true, "location": "https://www.test.net/home" } ] }

I hope this helps.

 

Regards

 

jjohnson
Nimbostratus
Nimbostratus

This does help a lot... still encountering some issues though... for the Boolean values if I send them as true of false I either get:

 

Invoke-RestMethod : {"code":400,"message":"Found unexpected json boolean at configuration item /ltm/policy/~Common~Drafts~TEST_POLICY_AUTOMATION/rules/Testing/conditions/equals. The json boolean is true.","errorStack":[],"apiError":1}

or

 

Invoke-RestMethod : {"code":400,"message":"Found unexpected json string at configuration item /ltm/policy/~Common~Drafts~TEST_POLICY_AUTOMATION/rules/Testing/conditions/equals. The json string is \"true\".","errorStack":[],"apiError":1}

This is the JSON I am using in my script, basing it off what you sent as a test

 

$ActionsBody = [ordered]@{ actions = @{ name = "0" request = $true forward = $true pool = '/Common/pool_test' } conditions =@{ name = "0" request = "true" httpHost = "true" equals = "true" values = "www.mydomain.net" } }   Invoke-RestMethod -Uri https://$url/mgmt/tm/ltm/policy/~Common~Drafts~$Policy/rules/Testing -Method PUT -Headers $Header -Body (ConvertTo-Json $ActionsBody) -ContentType 'application/json'

 

If I'm not wrong, PS writes True and False as first letter capitalized.

Try converting to a lower case string output and do not surround it with quotes.

This way works for you?

 

$ActionsBody = [ordered]@{ actions = @{ name = "0" request = $true forward = $true pool = '/Common/pool_test' } conditions =@{ name = "0" request = $true httpHost = $true equals = $true values = "www.mydomain.net" } } $ActionsBody |ConvertTo-Json

 

 

 

Regards

jjohnson
Nimbostratus
Nimbostratus

This is what I get now... Everything seems correct...

PS > $jsonBody = $ActionsBody | ConvertTo-Json   PS > $jsonBody   { "conditions": { "name": "0", "request": true, "httpHost": true, "equals": true, "values": "www.mydomain.net" } } PS > Invoke-RestMethod -Uri https://$url/mgmt/tm/ltm/policy/~Common~Drafts~$Policy/rules/Testing -Method PUT -Headers $Header -Body $jsonBody -ContentType 'application/json'   Invoke-RestMethod : {"code":400,"message":"Found unexpected json string at configuration item /ltm/policy/~Common~Drafts~TEST_POLICY_AUTOMATION/rules/Testing/conditions/name. The json string is

 

This way looks good for me:

 

$ActionsBody = [ordered]@{ actions = @{ name = "0" request = $true forward = $true pool = '/Common/pool_test' } conditions =@{ name = "0" request = $true httpHost = $true equals = $true values = "www.mydomain.net" } }   Invoke-RestMethod -Uri https://$url/mgmt/tm/ltm/policy/~Common~Drafts~$Policy/rules/Testing -Method PUT -Headers $Header -Body (ConvertTo-Json $ActionsBody) -ContentType 'application/json'

 

jjohnson
Nimbostratus
Nimbostratus

Alright... got it working!! Thank you for the assistance. I may be reaching out again before this is done 🙂

 

Here's what I did to get it working...

 

$ActionsBody = @" { "actions": [ { "name": "0", "request": true, "forward": true, "pool": "/Common/pool_test" } ], "conditions": [ { "name":"0", "request": true, "httpHost": true, "equals": true, "values": [ "www.mydomain.net" ] } ] } "@   Invoke-RestMethod -Uri https://$url/mgmt/tm/ltm/policy/~Common~Drafts~$Policy/rules/Testing -Method PUT -Headers $Header -Body $ActionsBody -ContentType 'application/json'

 

Yes, now I test it right.

We forgot that array collections: 😕

$ActionsBody = @{ actions = @( @{ name = "0" request = $true forward = $true pool = "/Common/pool_teste" } ) conditions = @( @{ name = "0" request = $true httpHost = $true equals = $true values = @("www.mydomain.net") } ) }   Invoke-RestMethod -Uri https://$url/mgmt/tm/ltm/policy/~Common~Drafts~$Policy/rules/Testing -Method PUT -Headers $Header -Body (ConvertTo-Json $ActionsBody -Depth 3) -ContentType 'application/json'