Demystifying iControl REST Part 7 - Understanding Transactions
I'm working on a python script which needs to create a LTM policy with 1 condition and 2 corresponding actions. Creating the policy and empty rule works like a charm but when I try adding the condition and actions in a transaction it fails.
def updatePolicy(partition, policyName, serverName, virtualServerName, env):
pol = ''
cCondition = {
u'name': u'0',
u'fullPath': u'0',
u'index': 0,
u'all': True,
u'caseInsensitive': True,
u'equals': True,
u'external': True,
u'httpHost': True,
u'present': True,
u'remote': True,
u'request': True,
u'values': [serverName]
}
cAction1 = {
u'name': u'0',
u'fullPath': u'0',
u'forwards': True,
u'request': True,
u'select': True,
u'virtual': u'/{0}/{1}'.format(partition, virtualServerName),
}
cAction2 = {
u'name': u'1',
u'fullPath': u'1',
u'disable': True,
u'request': True,
u'serverSsl': True,
}
try:
pol = mgmt.tm.ltm.policys.policy.load(name=policyName, partition=partition)
pol.draft()
except Exception as e:
try:
pol = mgmt.tm.ltm.policys.policy.load(name=policyName, partition=partition, subPath='Drafts')
print("...loaded policy draft")
except Exception as ee:
try:
pol = mgmt.tm.ltm.policys.policy.create(
name = policyName,
subPath = 'Drafts',
partition = partition,
ordinal = 0,
strategy = 'first-match',
controls = ["forwarding","server-ssl"],
requires = ["http"]
)
print("...created policy")
except Exception as eee:
print(eee)
sys.exit(1)
print("...adding rule to policy {0}".format(pol.name))
rules = pol.rules_s.get_collection()
rule = pol.rules_s.rules.create(
name = "rule-{0}".format(serverName),
subPath = 'Drafts',
ordinal = 0,
description = 'Redirect to /{0}/{1}'.format(partition, virtualServerName)
)
# Incorrect URI path must be corrected else setting condition won't work
rule._meta_data['uri'] = pol._meta_data['uri'] + 'rules/rule-{0}/'.format(serverName)
tx = mgmt.tm.transactions.transaction
with TransactionContextManager(tx) as api:
print("...add condition")
rule.conditions_s.conditions.create(**cCondition)
print("...add actions")
rule.actions_s.actions.create(**cAction1)
rule.actions_s.actions.create(**cAction2)
print("...updating rule")
rule.update()
pol.publish()
The issue I'm facing is maybe connected to the actions being added to the rule. When I run the script I receive the following output (rule is deleted manually before each run):
...loaded policy draft ...adding rule to policy policy-test-001 ...create rule ...add condition ...add actions Traceback (most recent call last): File "/usr/lib/python3.9/site-packages/f5/bigip/contexts.py", line 96, in __exit__ self.transaction.modify(state="VALIDATING", File "/usr/lib/python3.9/site-packages/f5/bigip/resource.py", line 423, in modify self._modify(**patch) File "/usr/lib/python3.9/site-packages/f5/bigip/resource.py", line 408, in _modify response = session.patch(patch_uri, json=patch, **requests_params) File "/usr/lib/python3.9/site-packages/icontrol/session.py", line 295, in wrapper raise iControlUnexpectedHTTPError(error_message, response=response) icontrol.exceptions.iControlUnexpectedHTTPError: 400 Unexpected Error: Bad Request for uri: https://10.0.0.10:443/mgmt/tm/transaction/1683888226128082/ Text: '{"code":400,"message":"transaction failed:0107186c:3: Policy \'/Common/Drafts/policy-test-001\', rule \'rule-test.local\'; missing or invalid target.","errorStack":[],"apiError":2}' During handling of the above exception, another exception occurred: Traceback (most recent call last): File "/var/www/apps/f5-python/./cert.py", line 239, in main(sys.argv[1:]) File "/var/www/apps/f5-python/./cert.py", line 236, in main updatePolicy('Common','policy-test-001', serverName, virtualServerName, environment) File "/var/www/apps/f5-python/./cert.py", line 184, in updatePolicy rule.actions_s.actions.create(**cAction2) File "/usr/lib/python3.9/site-packages/f5/bigip/contexts.py", line 100, in __exit__ raise TransactionSubmitException(e) f5.sdk_exception.TransactionSubmitException: 400 Unexpected Error: Bad Request for uri: https://10.0.0.10:443/mgmt/tm/transaction/1683888226128082/ Text: '{"code":400,"message":"transaction failed:0107186c:3: Policy \'/Common/Drafts/policy-test-001\', rule \'rule-test.local\'; missing or invalid target.","errorStack":[],"apiError":2}'
If I comment out the second action additition rule.actions_s.actions.create(**cAction2) I receive the same error but this time rule.actions_s.actions.create(**cAction1).
If both action lines are removed from the code the policy is updated but with only the condition.
Are there any specific things I need to keep in mind when adding actions to a rule and how can I change the code so that it works?