http headers incorrect after starting a second VSD session
Closed this issue · 2 comments
Problem description
Test automation requires the capability to define VSD session per enterprise to provide access to enterprises during test runs. It should be possible to perform CRUD actions on multiple enterprises over time.
Reproduction
- create 2 enterprises on 1 vsd (cluster)
- setup vsd session1 for enterprise1 (nume)
- setup vsd session2 for enterprise1 (nume)
- get first child of enterprise 1 using filter name=<enterprise_name> (nume object session1)
This result into a None object for first child. It looks like the HTTP header is garbeld with nume2 headers. This is clearly visible using robot framework output:
See log.html
session1: Return: <vspk.v6.nume.NUMe object at 0x7f0a64646208>
session2: Return: <vspk.v6.nume.NUMe object at 0x7f0a67fb4fd0>
Next the call to session1 to get enterprise by name from NUME object 0x7f0a64646208 (loggin session to se1-c1-v1 enterprise). From below excerpt you can see that the http header uses the wrong X-Nuage-Organization': 'se1-c5-v1' header. If the second session is not started, this test is successful.
Get the first child of a given kind
Start / End / Elapsed: 20200806 22:13:59.973 / 20200806 22:14:00.163 / 00:00:00.190
22:13:59.974 TRACE Arguments: [ obj=<vspk.v6.nume.NUMe object at 0x7f0a64646208> | attr='enterprises' | fltr='name is "se1-c1-v1"' ]
22:13:59.975 INFO > GET https://124.252.253.200:8443/nuage/api/v6/enterprises
22:13:59.975 DEBUG > headers: {'Content-Type': 'application/json', 'X-Nuage-Filter': 'name is "se1-c1-v1"', 'X-Nuage-Page': '0', 'X-Nuage-PageSize': '1', 'X-Nuage-Organization': 'se1-c5-v1', 'Authorization': 'XREST bWFyY3dvbGY6YzY2ZmRmM2ItMDVjZS00ZTA4LTlmOGMtMjQzYWU0MTQ5MGVj'}
22:13:59.976 DEBUG > data:
null
22:14:00.159 DEBUG https://124.252.253.200:8443 "GET /nuage/api/v6/enterprises HTTP/1.1" 200 0
22:14:00.161 INFO < GET https://124.252.253.200:8443/nuage/api/v6/enterprises [200]
22:14:00.161 DEBUG < headers: {'Server': 'Apache-Coyote/1.1', 'Pragma': 'No-cache', 'Cache-Control': 'no-cache', 'Expires': 'Wed, 31 Dec 1969 16:00:00 PST', 'Set-Cookie': 'rememberMe=deleteMe; Path=/nuage; Max-Age=0; Expires=Wed, 05-Aug-2020 20:14:01 GMT', 'X-Nuage-FilterType': 'none', 'X-Frame-Options': 'deny', 'X-Nuage-PageSize': '1', 'X-Nuage-Count': '0', 'Strict-Transport-Security': 'max-age=31536000', 'Access-Control-Expose-Headers': 'X-Nuage-Organization, X-Nuage-ProxyUser, X-Nuage-OrderBy, X-Nuage-FilterType, X-Nuage-Filter, X-Nuage-Page, X-Nuage-PageSize, X-Nuage-Count, X-Nuage-Custom, X-Nuage-ClientType, X-SSL-Client-CN, X-SSL-Client-ORG, X-SSL-Client-UID, X-SSL-Issuer-CN, X-SSL-Client-DN, X-SSL-Issuer-DN', 'X-Nuage-Filter': 'name is "se1-c1-v1"', 'Access-Control-Allow-Origin': '*', 'X-Nuage-OrderBy': 'name ASC', 'Content-Security-Policy': 'default-src', 'X-Nuage-Page': '0', 'X-XSS-Protection': '1', 'X-Content-Type-Options': 'nosniff', 'Referrer-Policy': 'origin', 'Content-Length': '0', 'Date': 'Thu, 06 Aug 2020 20:14:00 GMT'}
22:14:00.162 DEBUG < data:
null
22:14:00.162 TRACE Return: None
Attached:
- Robot Framework using VSDLib
- Python testscript including VSDLib class for Robot Framework
- Robot Framework html log file
test_vsd.py.txt
log.html.txt
bug.robot.txt
Run Python script:
(nuage-cats-6.0.5) marcwolf@laptop:~/tmp> pytest --disable-warnings --verbose test_vsd.py
==================================================== test session starts ====================================================
platform linux -- Python 3.6.10, pytest-6.0.1, py-1.9.0, pluggy-0.13.1 -- /home/marcwolf/venvs/nuage-cats-6.0.5/bin/python3
cachedir: .pytest_cache
rootdir: /home/marcwolf/tmp
collected 2 items
test_vsd.py::test_get_first_child PASSED [ 50%]
test_vsd.py::test_get_first_child_after_next_session FAILED [100%]
========================================================= FAILURES ==========================================================
__________________________________________ test_get_first_child_after_next_session __________________________________________
def test_get_first_child_after_next_session():
my_session1 = myVSD.start_vsd_session(url='https://124.252.253.200:8443',
enterprise='se1-c1-v1',
username='xxxxxxxxxxx',
password='xxxxxxxxxxx')
my_session2 = myVSD.start_vsd_session(url='https://124.252.253.200:8443',
enterprise='se1-c5-v1',
username='xxxxxxxxxx',
password='xxxxxxxxxx')
assert my_session1 is not None
assert my_session2 is not None
my_enterprise1 = myVSD.get_first_child(obj=my_session1, attr='enterprises', fltr='name is "se1-c1-v1"')
> assert my_enterprise1.name == 'se1-c1-v1'
E AttributeError: 'NoneType' object has no attribute 'name'
test_vsd.py:79: AttributeError
----------------------------------------------------- Captured log call -----------------------------------------------------
DEBUG vsdlib:test_vsd.py:22 > VSDLib: Start VSD Session using url: https://124.252.253.200:8443
DEBUG vsdlib:test_vsd.py:25 < VSDLib: Started VSD Session: <vspk.v6.nuvsdsession.NUVSDSession object at 0x7ff214e7c630>
DEBUG vsdlib:test_vsd.py:22 > VSDLib: Start VSD Session using url: https://124.252.253.200:8443
DEBUG vsdlib:test_vsd.py:25 < VSDLib: Started VSD Session: <vspk.v6.nuvsdsession.NUVSDSession object at 0x7ff214e7cb00>
================================================== short test summary info ==================================================
FAILED test_vsd.py::test_get_first_child_after_next_session - AttributeError: 'NoneType' object has no attribute 'name'
========================================== 1 failed, 1 passed, 3 warnings in 2.78s ==========================================
Hi @marcowenwolf,
Here's an example on how to use multiple sessions within the same script: https://github.com/nuagenetworks/vspk-examples/blob/master/python/multi-vsd_list_enterprises_domains_vms_structure_acls.py
This example uses different VSDs, but it is the same process for a single VSD environment, but have multiple users.
You need to use the python with
statement (https://docs.python.org/3/reference/compound_stmts.html#the-with-statement) for this functionality.
I hope that helps.
Hallo Phillipe,
Thanks for the quick response. The 'with' suggestion works as a charm. So it looks like you can pass on the session object correctly, but using the session.user object causes issues re-using fetchers in case of multiple VSD sessions. For me it makes sense to use session object to pass on with 'with' statement.
class VSDLib:
def start_vsd_session(self, url, username='csproot', password='csproot', enterprise='csp'):
logger.debug('> VSDLib: Start VSD Session using url: {}'.format(url))
nc = vsdk.NUVSDSession(username=username, password=password, enterprise=enterprise, api_url=url)
session = nc.start()
logger.debug('< VSDLib: Started VSD Session: {}'.format(session))
return session
def get_first_child(self, obj, attr, fltr=''):
"""Get the first child of a given kind
Arguments:
- obj -- the parent object
- attr -- the attribute name of the child type list
- fltr -- search filter
Returns:
- child object or None
Examples:
| ${r} = | Get First Child | obj=root | attr=enterprises | fltr=name is "sdnlight-t1" |
"""
with obj:
logger.debug('< get_first_child: {}, {}, {}'.format(obj, attr, fltr))
fetcher = obj.user.__dict__[attr]
child = fetcher.get_first(filter=fltr)
logger.debug('< Child: {}'.format(child))
return child