Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

problem with transactions using f5-sdk 1.3.1 and 11.6.1 #641

Closed
chen23 opened this issue Aug 19, 2016 · 8 comments
Closed

problem with transactions using f5-sdk 1.3.1 and 11.6.1 #641

chen23 opened this issue Aug 19, 2016 · 8 comments
Assignees

Comments

@chen23
Copy link

chen23 commented Aug 19, 2016

Testing on 11.6.1 w/ f5-sdk 1.3.1 ran into two issues with transactions

  1. transaction ID is seen as an "int" and causes the request to fail
  2. retrieving a "created" object messes up 'uri' and subsequent requests

I've patched my code to workaround the issues, not sure the best way to handle for the F5 Python SDK

Errors seen:

  1. error creating dora.local.pcfdev.io Header value 1471619352790463 must be of type str or bytes, not <type 'int'>
Traceback (most recent call last):
  File "cf2bigip-bad.py", line 592, in <module>
    sp.create_app(app_name, row[2], args.policy_name)
  File "cf2bigip-bad.py", line 339, in create_app
    pool_member = pool.members_s.members.create(partition=partition, name=member, priorityGroup=priority_group)
  File "/home/erchen/projects/pcf2bigip/venv/lib/python2.7/site-packages/f5/bigip/resource.py", line 851, in create
    return self._create(**kwargs)
  File "/home/erchen/projects/pcf2bigip/venv/lib/python2.7/site-packages/f5/bigip/resource.py", line 818, in _create
    response = session.post(_create_uri, json=kwargs, **requests_params)
  File "/home/erchen/projects/pcf2bigip/venv/lib/python2.7/site-packages/icontrol/session.py", line 230, in wrapper
    raise iControlUnexpectedHTTPError(error_message, response=response)
icontrol.exceptions.iControlUnexpectedHTTPError: 400 Unexpected Error: Bad Request for uri: https://10.1.10.240:443/mgmt/tm/transaction/1471619427763099/commands/2/members/
Text: u'{"code":400,"message":"Found invalid command id 2/members/","errorStack":[]}'

Code that avoids errors:

        with TransactionContextManager(self.tx) as api:
            # deal with ERROR #1: int vs. str
            api._meta_data['icr_session'].session.headers['X-F5-REST-Coordination-Id'] = api._meta_data['icr_session'].session.headers['X-F5-REST-Coordination-Id'].__str__()
            monitor = api.tm.ltm.monitor.https.http.create(name=monitor_name, partition=partition, interval=10, timeout=31, send=send_str, recv=recv_str)
            pool_path = "/%s/%s" % (partition, pool_name)

            pool = api.tm.ltm.pools.pool.create(partition=partition, name=pool_name, minActiveMembers=1, monitor=monitor_name)
            print "Created pool %s" % pool_path

            member_list = pool_members.split(',')
            member_list.reverse()
            priority_group = 0
            for member in member_list:
                # deal with ERROR #2 incorrect URI path
                pool._meta_data['uri'] = pool._meta_data['uri'].split("/transaction/")[0] + "/ltm/pool/~%s~%s/" %(partition,pool_name)
                pool_member = pool.members_s.members.create(partition=partition, name=member, priorityGroup=priority_group)
                priority_group += 10
                print " Added member %s" % member

            policy = api.tm.ltm.policys.policy.load(name = policy_name, partition = partition)

            rules = policy.rules_s.get_collection()

            my_rule = policy.rules_s.rules.create(name=app_name)

            payload = {u'caseInsensitive': True,
                   u'equals': True,
                   u'external': True,
                   u'fullPath': u'0',
                   u'host': True,
                   u'httpHost': True,
                   u'index': 0,
                   u'name': u'0',
                   u'present': True,
                   u'remote': True,
                   u'request': True,
                   u'values': [app_name]}
            # deal with ERROR #2 incorrect URI path
            my_rule._meta_data['uri'] = policy._meta_data['uri'] + 'rules/' + app_name + '/'
            my_rule.conditions_s.conditions.create(**payload)
            payload = {
                "vlanId": 0,
                "forward": True,
                "code": 0,
                "fullPath": "0",
                "name": "0",
                "pool": pool_name,
                "request": True,
                "select": True,
                "status": 0
        }
            my_rule.actions_s.actions.create(**payload)
@zancas
Copy link
Contributor

zancas commented Aug 22, 2016

@chen23 how about deleting the pool_path = line and having the print debug statement that used it be:

print("Created pool %s" % pool.selfLink)

instead?

@zancas
Copy link
Contributor

zancas commented Aug 22, 2016

Instead of directly calling instance.__str__() call str(instance).

@chen23
Copy link
Author

chen23 commented Aug 22, 2016

Here's the output with the suggested changes:

 python cf2bigip-bad.py -f create.csv 10.1.1.5
create.csv
Created pool https://localhost/mgmt/tm/transaction/1471889627257896/commands/2?ver=11.6.1
 Added member 192.168.11.11:80
Created policy rule dora.local.pcfdev.io

@caphrim007
Copy link
Contributor

@chen23 do you have code I can use to reproduce?

@zancas
Copy link
Contributor

zancas commented Aug 23, 2016

And I!

@caphrim007
Copy link
Contributor

This is a breaking change introduced in requests 2.11 https://github.com/kennethreitz/requests/issues/3477

caphrim007 added a commit to caphrim007/f5-common-python that referenced this issue Aug 23, 2016
Issues:
Fixes F5Networks#641

Problem:
requests 2.11 changed compatibility to disallow integers inside of headers.
The result was that the transaction functionality in the SDK broke because
transaction IDs are integers and sent in the headers of the request
(X-F5-REST-Coordination-Id).

Analysis:
This patch casts the integers to strings to correct the problem.

Tests:
none
@chen23
Copy link
Author

chen23 commented Aug 30, 2016

A bit late. Here's the code: https://github.com/f5devcentral/f5-icontrol-codeshare-python/tree/master/pcf-example, use pcf-phase1.py.

The issue had two issues: 1. transaction ID in header 2. URI getting mangled during a transaction. Let me know if I should open a new ticket for the second issue, reopen, or leave my code as-is. Thanks.

@r4mbo7
Copy link

r4mbo7 commented Mar 2, 2020

Thanks @chen23 for your fixes !

I tried to create a virtual server with a member using a same transaction. Using f5-sdk==3.0.21

E           icontrol.exceptions.iControlUnexpectedHTTPError: 400 Unexpected Error: Bad Request for uri: https://lb-bigip01/mgmt/tm/transaction/1583156579056330/commands/3/members/
E           Text: '{"code":400,"message":"Found invalid command id 3/members/","errorStack":[],"apiError":1}'

Code to reproduce

host = os.getenv("BIGIP_BENCH_HOST")
user = os.getenv("BIGIP_BENCH_USER")
password = os.getenv("BIGIP_BENCH_PASSWORD")
mgmt = ManagementRoot(host, user, password)
tx = mgmt.tm.transactions.transaction
with TransactionContextManager(tx) as api:
    https_monitor = api.tm.ltm.monitor.https_s.https.create(name="MyHttpsMonitor")
    # create a node
    node = api.tm.ltm.nodes.node.create(name="MyNode", address="1.2.3.4")
    # create a pool
    pool_name = "MyPool"
    partition = "Common"
    pool = api.tm.ltm.pools.pool.create(
        name=pool_name,
        loadBalancingMode="round-robin",
        monitor="MyHttpsMonitor",
        partition=partition
    )
    # Fixes {"code":400,"message":"Found invalid command id 3/members/","errorStack":[],"apiError":1}
    # pool._meta_data['uri'] = pool._meta_data['uri'].split("/transaction/")[0] + "/ltm/pool/~%s~%s/" %(partition, pool_name)
    # create a pool member - inherit monitor from pool.
    member = pool.members_s.members.create(
        name="MyNode:42", address="1.2.3.4", partition="Common"
    )
    # create vip
    vip = api.tm.ltm.virtuals.virtual.create(
        name="MyVip", pool=pool_name, source="0.0.0.0/0", destination="1.2.3.4:42"
    )

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants