Skip to content

Commit 84d2b6e

Browse files
committed
Adds support for validate_only to the transaction
Issues: Fixes #653 Problem: The validateOnly functionality of transactions was not exposed to the end user. Therefore, the user could never know if the transaction would pass or fail if they ran it without actually running it Analysis: This patch adds support to the TransactionContextManager so that it allows for the validate_only parameter to be provided. By default, this parameter is set to False to maintain backwards compatibility. Tests: tests/functional/tm/transaction/test_transaction.py::TestTransaction::test_validate_only_true
1 parent 3882277 commit 84d2b6e

2 files changed

Lines changed: 69 additions & 3 deletions

File tree

f5/bigip/contexts.py

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,33 @@ class TransactionSubmitException(F5SDKError):
2727

2828

2929
class TransactionContextManager(object):
30-
def __init__(self, transaction):
30+
def __init__(self, transaction, validate_only=False):
31+
"""Initialize a new Transaction context
32+
33+
Args:
34+
validate_only (bool): Will not commit the transaction, but only
35+
validate that it will succeed or not.
36+
37+
Attributes:
38+
transaction (Transaction): The transaction object that was sent
39+
to the context manager
40+
validate_only (bool): Specifies whether the transaction should
41+
commit itself upon `__exit__` or whether the commands in the
42+
transaction should just be checked to make sure they don't
43+
raise an error.
44+
bigip (dict): A reference to the dictionary containing the BIG-IP
45+
mgmt_root
46+
icr (iControlRESTSession): A reference to the dictionary
47+
containing the iControl REST session
48+
original_headers (dict): A deep copy of all the headers that were
49+
originally part of the iControl REST session. A copy is needed
50+
so that we can revert back to them after the transaction has
51+
been committed, since the only way to commit the transaction
52+
is to set the X-F5-REST-Coordination-Id to the value of the
53+
transaction ID of the transaction.
54+
"""
3155
self.transaction = transaction
56+
self.validate_only = validate_only
3257
self.bigip = transaction._meta_data['bigip']
3358
self.icr = self.bigip._meta_data['icr_session']
3459
self.original_headers = copy.deepcopy(self.icr.session.headers)
@@ -68,10 +93,12 @@ def __exit__(self, exc_type, exc_value, exc_tb):
6893
parameters will be None
6994
:returns: void
7095
"""
96+
7197
self.icr.session.headers = dict()
7298
if exc_tb is None:
7399
try:
74-
self.transaction.update(state="VALIDATING")
100+
self.transaction.modify(state="VALIDATING",
101+
validateOnly=self.validate_only)
75102
except Exception as e:
76103
logging.debug(e)
77104
raise TransactionSubmitException(e)

test/functional/tm/transaction/test_transaction.py

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515

1616
import pytest
1717

18+
from distutils.version import LooseVersion
1819
from f5.bigip.contexts import TransactionContextManager
1920
from f5.bigip.contexts import TransactionSubmitException
2021

@@ -34,4 +35,42 @@ def test_create_empty(self, mgmt_root):
3435
with TransactionContextManager(tx) as api: # NOQA
3536
pass
3637
assert "there is no command to commit in the transaction" \
37-
in str(ex.value.message)
38+
in str(ex.value)
39+
40+
@pytest.mark.skipif(
41+
LooseVersion(pytest.config.getoption('--release'))
42+
< LooseVersion('12.0.0'),
43+
reason='Needs v12.0.0 TMOS or greater to pass.'
44+
)
45+
def test_validate_only_true(self, mgmt_root):
46+
s1 = mgmt_root.tm.sys.dbs.db.load(name='setup.run')
47+
s1.update(value=False)
48+
49+
tx = mgmt_root.tm.transactions.transaction
50+
with TransactionContextManager(tx, validate_only=True) as api: # NOQA
51+
s2 = api.tm.sys.dbs.db.load(name='setup.run')
52+
s2.update(value=True)
53+
54+
s3 = mgmt_root.tm.sys.dbs.db.load(name='setup.run')
55+
result = s3.value
56+
57+
assert result == 'false'
58+
59+
@pytest.mark.skipif(
60+
LooseVersion(pytest.config.getoption('--release'))
61+
< LooseVersion('12.0.0'),
62+
reason='Needs v12.0.0 TMOS or greater to pass.'
63+
)
64+
def test_validate_only_false(self, mgmt_root):
65+
s1 = mgmt_root.tm.sys.dbs.db.load(name='setup.run')
66+
s1.update(value=False)
67+
68+
tx = mgmt_root.tm.transactions.transaction
69+
with TransactionContextManager(tx, validate_only=False) as api: # NOQA
70+
s2 = api.tm.sys.dbs.db.load(name='setup.run')
71+
s2.update(value=True)
72+
73+
s3 = mgmt_root.tm.sys.dbs.db.load(name='setup.run')
74+
result = s3.value
75+
76+
assert result == 'true'

0 commit comments

Comments
 (0)