Technical Forum
Ask questions. Discover Answers.
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'