Forum Discussion

jjohnson's avatar
jjohnson
Icon for Nimbostratus rankNimbostratus
Jul 02, 2020

iControl REST API Policy Rules

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

  • 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

     

  • 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'

     

    • cjunior's avatar
      cjunior
      Icon for Nacreous rankNacreous

      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

  • 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

     

    • cjunior's avatar
      cjunior
      Icon for Nacreous rankNacreous

      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'
  • 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'
    • cjunior's avatar
      cjunior
      Icon for Nacreous rankNacreous

      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'