Create session for XSRF token
To avoid CSRF attacks, the requests to the NSX manager should have X-XSRF-TOKEN header. To get it, and the JSESSIONID, the cluster will issue a session/create request for each endpoint at init, and retrieve the values from the response header. Those values will later be used for each request to this endpoint. Change-Id: I24cf6416e38dc7f57d7d8ceece48a1d3d5815112
This commit is contained in:
parent
2a68ede0c0
commit
5467ac673a
|
@ -20,6 +20,7 @@ import mock
|
|||
from oslo_serialization import jsonutils
|
||||
from oslo_utils import uuidutils
|
||||
from requests import exceptions as requests_exceptions
|
||||
from requests import models
|
||||
|
||||
from vmware_nsxlib import v3
|
||||
from vmware_nsxlib.v3 import client as nsx_client
|
||||
|
@ -47,6 +48,8 @@ PLUGIN_VER = "plugin ver"
|
|||
DNS_NAMESERVERS = ['1.1.1.1']
|
||||
DNS_DOMAIN = 'openstacklocal'
|
||||
|
||||
JSESSIONID = 'my_sess_id'
|
||||
|
||||
|
||||
def _mock_nsxlib():
|
||||
def _return_id_key(*args, **kwargs):
|
||||
|
@ -316,8 +319,28 @@ class NsxClientTestCase(NsxLibTestCase):
|
|||
assert conn is not None
|
||||
|
||||
def mock_nsx_clustered_api(self, session_response=None, **kwargs):
|
||||
return NsxClientTestCase.MockNSXClusteredAPI(
|
||||
session_response=session_response, **kwargs)
|
||||
orig_request = nsx_cluster.TimeoutSession.request
|
||||
|
||||
def mocked_request(*args, **kwargs):
|
||||
if args[2].endswith('api/session/create'):
|
||||
response = models.Response()
|
||||
response.status_code = 200
|
||||
response.headers = {
|
||||
'Set-Cookie': 'JSESSIONID=%s;junk' % JSESSIONID}
|
||||
return response
|
||||
return orig_request(*args, **kwargs)
|
||||
|
||||
with mock.patch.object(nsx_cluster.TimeoutSession, 'request',
|
||||
new=mocked_request):
|
||||
cluster = NsxClientTestCase.MockNSXClusteredAPI(
|
||||
session_response=session_response, **kwargs)
|
||||
return cluster
|
||||
|
||||
@staticmethod
|
||||
def default_headers():
|
||||
return {'Content-Type': 'application/json',
|
||||
'Accept': 'application/json',
|
||||
'Cookie': 'JSESSIONID=%s;' % JSESSIONID}
|
||||
|
||||
def mocked_resource(self, resource_class, mock_validate=True,
|
||||
session_response=None):
|
||||
|
@ -368,12 +391,14 @@ class NsxClientTestCase(NsxLibTestCase):
|
|||
return nsx_cluster.NSXClusteredAPI(nsxlib_config)
|
||||
|
||||
def assert_json_call(self, method, client, url,
|
||||
headers=nsx_client.JSONRESTClient._DEFAULT_HEADERS,
|
||||
headers=None,
|
||||
timeout=(NSX_HTTP_TIMEOUT, NSX_HTTP_READ_TIMEOUT),
|
||||
data=None):
|
||||
cluster = client._conn
|
||||
if data:
|
||||
data = jsonutils.dumps(data, sort_keys=True)
|
||||
if not headers:
|
||||
headers = self.default_headers()
|
||||
cluster.assert_called_once(
|
||||
method,
|
||||
**{'url': url, 'verify': NSX_CERT, 'body': data,
|
||||
|
|
|
@ -30,7 +30,14 @@ LOG = log.getLogger(__name__)
|
|||
CLIENT_PKG = 'vmware_nsxlib.v3.client'
|
||||
|
||||
DFT_ACCEPT_HEADERS = {
|
||||
'Accept': '*/*'
|
||||
'Accept': '*/*',
|
||||
'Cookie': 'JSESSIONID=%s;' % nsxlib_testcase.JSESSIONID
|
||||
}
|
||||
|
||||
JSON_DFT_ACCEPT_HEADERS = {
|
||||
'Accept': 'application/json',
|
||||
'Content-Type': 'application/json',
|
||||
'Cookie': 'JSESSIONID=%s;' % nsxlib_testcase.JSESSIONID
|
||||
}
|
||||
|
||||
|
||||
|
@ -65,7 +72,7 @@ def assert_call(verb, client_or_resource,
|
|||
def assert_json_call(verb, client_or_resource, url,
|
||||
verify=nsxlib_testcase.NSX_CERT,
|
||||
data=None,
|
||||
headers=client.JSONRESTClient._DEFAULT_HEADERS,
|
||||
headers=JSON_DFT_ACCEPT_HEADERS,
|
||||
single_call=True):
|
||||
return assert_call(verb, client_or_resource, url,
|
||||
verify=verify, data=data,
|
||||
|
|
|
@ -18,6 +18,7 @@ import unittest
|
|||
import mock
|
||||
from oslo_serialization import jsonutils
|
||||
from requests import exceptions as requests_exceptions
|
||||
from requests import models
|
||||
import six.moves.urllib.parse as urlparse
|
||||
|
||||
from vmware_nsxlib.tests.unit.v3 import mocks
|
||||
|
@ -36,6 +37,13 @@ def _validate_conn_down(*args, **kwargs):
|
|||
raise requests_exceptions.ConnectionError()
|
||||
|
||||
|
||||
def get_sess_create_resp():
|
||||
sess_create_response = models.Response()
|
||||
sess_create_response.status_code = 200
|
||||
sess_create_response.headers = {'Set-Cookie': 'JSESSIONID=abc;'}
|
||||
return sess_create_response
|
||||
|
||||
|
||||
class RequestsHTTPProviderTestCase(unittest.TestCase):
|
||||
|
||||
def test_new_connection(self):
|
||||
|
@ -50,15 +58,18 @@ class RequestsHTTPProviderTestCase(unittest.TestCase):
|
|||
mock_api.nsxlib_config.conn_idle_timeout = 39
|
||||
mock_api.nsxlib_config.client_cert_provider = None
|
||||
provider = cluster.NSXRequestsHTTPProvider()
|
||||
session = provider.new_connection(
|
||||
mock_api, cluster.Provider('9.8.7.6', 'https://9.8.7.6',
|
||||
'nsxuser', 'nsxpassword', None))
|
||||
with mock.patch.object(cluster.TimeoutSession, 'request',
|
||||
return_value=get_sess_create_resp()):
|
||||
session = provider.new_connection(
|
||||
mock_api, cluster.Provider('9.8.7.6', 'https://9.8.7.6',
|
||||
'nsxuser', 'nsxpassword', None))
|
||||
|
||||
self.assertEqual(('nsxuser', 'nsxpassword'), session.auth)
|
||||
self.assertFalse(session.verify)
|
||||
self.assertIsNone(session.cert)
|
||||
self.assertEqual(100, session.adapters['https://'].max_retries.total)
|
||||
self.assertEqual(99, session.timeout)
|
||||
self.assertEqual(('nsxuser', 'nsxpassword'), session.auth)
|
||||
self.assertFalse(session.verify)
|
||||
self.assertIsNone(session.cert)
|
||||
self.assertEqual(100,
|
||||
session.adapters['https://'].max_retries.total)
|
||||
self.assertEqual(99, session.timeout)
|
||||
|
||||
def test_new_connection_with_client_auth(self):
|
||||
mock_api = mock.Mock()
|
||||
|
@ -72,14 +83,16 @@ class RequestsHTTPProviderTestCase(unittest.TestCase):
|
|||
'/etc/cert.pem')
|
||||
mock_api.nsxlib_config.client_cert_provider = cert_provider_inst
|
||||
provider = cluster.NSXRequestsHTTPProvider()
|
||||
session = provider.new_connection(
|
||||
mock_api, cluster.Provider('9.8.7.6', 'https://9.8.7.6',
|
||||
None, None, None))
|
||||
with mock.patch.object(cluster.TimeoutSession, 'request',
|
||||
return_value=get_sess_create_resp()):
|
||||
session = provider.new_connection(
|
||||
mock_api, cluster.Provider('9.8.7.6', 'https://9.8.7.6',
|
||||
None, None, None))
|
||||
|
||||
self.assertIsNone(session.auth)
|
||||
self.assertFalse(session.verify)
|
||||
self.assertEqual(cert_provider_inst, session.cert_provider)
|
||||
self.assertEqual(99, session.timeout)
|
||||
self.assertIsNone(session.auth)
|
||||
self.assertFalse(session.verify)
|
||||
self.assertEqual(cert_provider_inst, session.cert_provider)
|
||||
self.assertEqual(99, session.timeout)
|
||||
|
||||
def test_validate_connection(self):
|
||||
self.skipTest("Revist")
|
||||
|
@ -231,6 +244,8 @@ class ClusteredAPITestCase(nsxlib_testcase.NsxClientTestCase):
|
|||
self.assertEqual(_get_schedule(4), [eps[0], eps[2], eps[0], eps[2]])
|
||||
|
||||
def test_reinitialize_cluster(self):
|
||||
api = self.mock_nsx_clustered_api()
|
||||
# just make sure this api is defined, and does not crash
|
||||
api._reinit_cluster()
|
||||
with mock.patch.object(cluster.TimeoutSession, 'request',
|
||||
return_value=get_sess_create_resp()):
|
||||
api = self.mock_nsx_clustered_api()
|
||||
# just make sure this api is defined, and does not crash
|
||||
api._reinit_cluster()
|
||||
|
|
|
@ -53,7 +53,8 @@ class TestSwitchingProfileTestCase(nsxlib_testcase.NsxClientTestCase):
|
|||
'resource_type': profile_types.PORT_MIRRORING,
|
||||
'display_name': 'pm-profile',
|
||||
'description': 'port mirror prof'
|
||||
}, sort_keys=True))
|
||||
}, sort_keys=True),
|
||||
headers=self.default_headers())
|
||||
|
||||
def test_switching_profile_update(self):
|
||||
|
||||
|
@ -79,7 +80,8 @@ class TestSwitchingProfileTestCase(nsxlib_testcase.NsxClientTestCase):
|
|||
data=jsonutils.dumps({
|
||||
'resource_type': profile_types.PORT_MIRRORING,
|
||||
'tags': tags
|
||||
}, sort_keys=True))
|
||||
}, sort_keys=True),
|
||||
headers=self.default_headers())
|
||||
|
||||
def test_spoofgaurd_profile_create(self):
|
||||
|
||||
|
@ -109,7 +111,8 @@ class TestSwitchingProfileTestCase(nsxlib_testcase.NsxClientTestCase):
|
|||
'description': 'spoofguard-for-plugin',
|
||||
'white_list_providers': ['LPORT_BINDINGS'],
|
||||
'tags': tags
|
||||
}, sort_keys=True))
|
||||
}, sort_keys=True),
|
||||
headers=self.default_headers())
|
||||
|
||||
def test_create_dhcp_profile(self):
|
||||
|
||||
|
@ -154,7 +157,8 @@ class TestSwitchingProfileTestCase(nsxlib_testcase.NsxClientTestCase):
|
|||
'tx_multicast': 0
|
||||
},
|
||||
'block_non_ip_traffic': True
|
||||
}, sort_keys=True))
|
||||
}, sort_keys=True),
|
||||
headers=self.default_headers())
|
||||
|
||||
def test_create_mac_learning_profile(self):
|
||||
|
||||
|
@ -187,7 +191,8 @@ class TestSwitchingProfileTestCase(nsxlib_testcase.NsxClientTestCase):
|
|||
'description': 'mac-learning-for-plugin',
|
||||
'tags': tags,
|
||||
'mac_change_allowed': True,
|
||||
}, sort_keys=True))
|
||||
}, sort_keys=True),
|
||||
headers=self.default_headers())
|
||||
|
||||
def test_find_by_display_name(self):
|
||||
resp_resources = {
|
||||
|
@ -230,7 +235,8 @@ class TestSwitchingProfileTestCase(nsxlib_testcase.NsxClientTestCase):
|
|||
'get', mocked_resource,
|
||||
'https://1.2.3.4/api/v1/switching-profiles/'
|
||||
'?include_system_owned=True',
|
||||
data=None)
|
||||
data=None,
|
||||
headers=self.default_headers())
|
||||
|
||||
|
||||
class LogicalPortTestCase(nsxlib_testcase.NsxClientTestCase):
|
||||
|
@ -300,7 +306,8 @@ class LogicalPortTestCase(nsxlib_testcase.NsxClientTestCase):
|
|||
test_client.assert_json_call(
|
||||
'post', mocked_resource,
|
||||
'https://1.2.3.4/api/v1/logical-ports',
|
||||
data=jsonutils.dumps(resp_body, sort_keys=True))
|
||||
data=jsonutils.dumps(resp_body, sort_keys=True),
|
||||
headers=self.default_headers())
|
||||
|
||||
def test_create_logical_port_with_attachtype_cif(self):
|
||||
"""Test creating a port returns the correct response and 200 status
|
||||
|
@ -353,7 +360,8 @@ class LogicalPortTestCase(nsxlib_testcase.NsxClientTestCase):
|
|||
test_client.assert_json_call(
|
||||
'post', mocked_resource,
|
||||
'https://1.2.3.4/api/v1/logical-ports',
|
||||
data=jsonutils.dumps(resp_body, sort_keys=True))
|
||||
data=jsonutils.dumps(resp_body, sort_keys=True),
|
||||
headers=self.default_headers())
|
||||
|
||||
def test_create_logical_port_admin_down(self):
|
||||
"""Test creating port with admin_state down."""
|
||||
|
@ -379,7 +387,8 @@ class LogicalPortTestCase(nsxlib_testcase.NsxClientTestCase):
|
|||
mocked_resource.delete(uuid)
|
||||
test_client.assert_json_call(
|
||||
'delete', mocked_resource,
|
||||
'https://1.2.3.4/api/v1/logical-ports/%s?detach=true' % uuid)
|
||||
'https://1.2.3.4/api/v1/logical-ports/%s?detach=true' % uuid,
|
||||
headers=self.default_headers())
|
||||
|
||||
def test_get_logical_port_by_attachment(self):
|
||||
"""Test deleting port."""
|
||||
|
@ -390,7 +399,8 @@ class LogicalPortTestCase(nsxlib_testcase.NsxClientTestCase):
|
|||
test_client.assert_json_call(
|
||||
'get', mocked_resource,
|
||||
"https://1.2.3.4/api/v1/logical-ports/?attachment_type=%s"
|
||||
"&attachment_id=%s" % (attachment_type, attachment_id))
|
||||
"&attachment_id=%s" % (attachment_type, attachment_id),
|
||||
headers=self.default_headers())
|
||||
|
||||
def test_clear_port_bindings(self):
|
||||
fake_port = copy.copy(test_constants.FAKE_PORT)
|
||||
|
@ -408,7 +418,8 @@ class LogicalPortTestCase(nsxlib_testcase.NsxClientTestCase):
|
|||
test_client.assert_json_call(
|
||||
'put', mocked_resource,
|
||||
'https://1.2.3.4/api/v1/logical-ports/%s' % fake_port['id'],
|
||||
data=jsonutils.dumps(fake_port, sort_keys=True))
|
||||
data=jsonutils.dumps(fake_port, sort_keys=True),
|
||||
headers=self.default_headers())
|
||||
|
||||
def test_create_logical_port_fail(self):
|
||||
"""Test the failure of port creation."""
|
||||
|
@ -464,7 +475,8 @@ class LogicalRouterTestCase(nsxlib_testcase.NsxClientTestCase):
|
|||
test_client.assert_json_call(
|
||||
'post', router,
|
||||
'https://1.2.3.4/api/v1/logical-routers',
|
||||
data=jsonutils.dumps(data, sort_keys=True))
|
||||
data=jsonutils.dumps(data, sort_keys=True),
|
||||
headers=self.default_headers())
|
||||
|
||||
def test_delete_logical_router(self):
|
||||
"""Test deleting router"""
|
||||
|
@ -473,7 +485,8 @@ class LogicalRouterTestCase(nsxlib_testcase.NsxClientTestCase):
|
|||
router.delete(uuid)
|
||||
test_client.assert_json_call(
|
||||
'delete', router,
|
||||
'https://1.2.3.4/api/v1/logical-routers/%s' % uuid)
|
||||
'https://1.2.3.4/api/v1/logical-routers/%s' % uuid,
|
||||
headers=self.default_headers())
|
||||
|
||||
def test_force_delete_logical_router(self):
|
||||
"""Test force deleting router"""
|
||||
|
@ -482,7 +495,8 @@ class LogicalRouterTestCase(nsxlib_testcase.NsxClientTestCase):
|
|||
router.delete(uuid, True)
|
||||
test_client.assert_json_call(
|
||||
'delete', router,
|
||||
'https://1.2.3.4/api/v1/logical-routers/%s?force=True' % uuid)
|
||||
'https://1.2.3.4/api/v1/logical-routers/%s?force=True' % uuid,
|
||||
headers=self.default_headers())
|
||||
|
||||
def test_get_logical_router_fw_section(self):
|
||||
fake_router = test_constants.FAKE_ROUTER.copy()
|
||||
|
@ -520,7 +534,8 @@ class LogicalRouterTestCase(nsxlib_testcase.NsxClientTestCase):
|
|||
'post', router,
|
||||
('https://1.2.3.4/api/v1/logical-routers/%s/nat/rules' %
|
||||
test_constants.FAKE_ROUTER_UUID),
|
||||
data=jsonutils.dumps(data, sort_keys=True))
|
||||
data=jsonutils.dumps(data, sort_keys=True),
|
||||
headers=self.default_headers())
|
||||
|
||||
def test_nat_rule_create_v1(self):
|
||||
# Ignoring 'bypass_firewall' with version 1.1
|
||||
|
@ -536,7 +551,8 @@ class LogicalRouterTestCase(nsxlib_testcase.NsxClientTestCase):
|
|||
test_client.assert_json_call(
|
||||
'get', router,
|
||||
('https://1.2.3.4/api/v1/logical-routers/%s/nat/rules' %
|
||||
test_constants.FAKE_ROUTER_UUID))
|
||||
test_constants.FAKE_ROUTER_UUID),
|
||||
headers=self.default_headers())
|
||||
|
||||
def test_nat_rule_update(self):
|
||||
router = self._mocked_lrouter()
|
||||
|
@ -550,7 +566,8 @@ class LogicalRouterTestCase(nsxlib_testcase.NsxClientTestCase):
|
|||
'put', router,
|
||||
('https://1.2.3.4/api/v1/logical-routers/%s/nat/rules/%s' %
|
||||
(test_constants.FAKE_ROUTER_UUID, rule_id)),
|
||||
data=jsonutils.dumps(data, sort_keys=True))
|
||||
data=jsonutils.dumps(data, sort_keys=True),
|
||||
headers=self.default_headers())
|
||||
|
||||
def test_delete_nat_rule_by_gw(self):
|
||||
router = self._mocked_lrouter()
|
||||
|
@ -569,7 +586,8 @@ class LogicalRouterTestCase(nsxlib_testcase.NsxClientTestCase):
|
|||
test_client.assert_json_call(
|
||||
'delete', router,
|
||||
('https://1.2.3.4/api/v1/logical-routers/%s/nat/rules/%s' %
|
||||
(test_constants.FAKE_ROUTER_UUID, rule_id)))
|
||||
(test_constants.FAKE_ROUTER_UUID, rule_id)),
|
||||
headers=self.default_headers())
|
||||
|
||||
def test_delete_nat_rule_by_gw_and_source(self):
|
||||
router = self._mocked_lrouter()
|
||||
|
@ -591,7 +609,8 @@ class LogicalRouterTestCase(nsxlib_testcase.NsxClientTestCase):
|
|||
test_client.assert_json_call(
|
||||
'delete', router,
|
||||
('https://1.2.3.4/api/v1/logical-routers/%s/nat/rules/%s' %
|
||||
(test_constants.FAKE_ROUTER_UUID, rule_id)))
|
||||
(test_constants.FAKE_ROUTER_UUID, rule_id)),
|
||||
headers=self.default_headers())
|
||||
|
||||
|
||||
class LogicalRouterPortTestCase(nsxlib_testcase.NsxClientTestCase):
|
||||
|
@ -631,7 +650,8 @@ class LogicalRouterPortTestCase(nsxlib_testcase.NsxClientTestCase):
|
|||
test_client.assert_json_call(
|
||||
'post', lrport,
|
||||
'https://1.2.3.4/api/v1/logical-router-ports',
|
||||
data=jsonutils.dumps(data, sort_keys=True))
|
||||
data=jsonutils.dumps(data, sort_keys=True),
|
||||
headers=self.default_headers())
|
||||
|
||||
def test_logical_router_port_max_attempts(self):
|
||||
"""Test a router port api has the configured retries."""
|
||||
|
@ -648,7 +668,8 @@ class LogicalRouterPortTestCase(nsxlib_testcase.NsxClientTestCase):
|
|||
lrport.delete(uuid)
|
||||
test_client.assert_json_call(
|
||||
'delete', lrport,
|
||||
'https://1.2.3.4/api/v1/logical-router-ports/%s' % uuid)
|
||||
'https://1.2.3.4/api/v1/logical-router-ports/%s' % uuid,
|
||||
headers=self.default_headers())
|
||||
|
||||
def test_update_logical_router_port(self):
|
||||
fake_router_port = test_constants.FAKE_ROUTER_PORT.copy()
|
||||
|
@ -674,7 +695,8 @@ class LogicalRouterPortTestCase(nsxlib_testcase.NsxClientTestCase):
|
|||
test_client.assert_json_call(
|
||||
'put', lrport,
|
||||
'https://1.2.3.4/api/v1/logical-router-ports/%s' % uuid,
|
||||
data=jsonutils.dumps(data, sort_keys=True))
|
||||
data=jsonutils.dumps(data, sort_keys=True),
|
||||
headers=self.default_headers())
|
||||
|
||||
def test_get_logical_router_port_by_router_id(self):
|
||||
"""Test getting a router port by router id."""
|
||||
|
@ -691,7 +713,8 @@ class LogicalRouterPortTestCase(nsxlib_testcase.NsxClientTestCase):
|
|||
test_client.assert_json_call(
|
||||
'get', lrport,
|
||||
'https://1.2.3.4/api/v1/logical-router-ports/?'
|
||||
'logical_router_id=%s' % router_id)
|
||||
'logical_router_id=%s' % router_id,
|
||||
headers=self.default_headers())
|
||||
|
||||
def test_get_logical_router_port_by_switch_id(self):
|
||||
"""Test getting a router port by switch id."""
|
||||
|
@ -710,7 +733,8 @@ class LogicalRouterPortTestCase(nsxlib_testcase.NsxClientTestCase):
|
|||
test_client.assert_json_call(
|
||||
'get', lrport,
|
||||
'https://1.2.3.4/api/v1/logical-router-ports/?'
|
||||
'logical_switch_id=%s' % switch_id)
|
||||
'logical_switch_id=%s' % switch_id,
|
||||
headers=self.default_headers())
|
||||
|
||||
|
||||
class IpPoolTestCase(nsxlib_testcase.NsxClientTestCase):
|
||||
|
@ -753,7 +777,8 @@ class IpPoolTestCase(nsxlib_testcase.NsxClientTestCase):
|
|||
test_client.assert_json_call(
|
||||
'post', pool,
|
||||
'https://1.2.3.4/api/v1/pools/ip-pools',
|
||||
data=jsonutils.dumps(data, sort_keys=True))
|
||||
data=jsonutils.dumps(data, sort_keys=True),
|
||||
headers=self.default_headers())
|
||||
|
||||
def test_create_ip_pool_minimal_args(self):
|
||||
pool = self._mocked_pool()
|
||||
|
@ -773,7 +798,8 @@ class IpPoolTestCase(nsxlib_testcase.NsxClientTestCase):
|
|||
test_client.assert_json_call(
|
||||
'post', pool,
|
||||
'https://1.2.3.4/api/v1/pools/ip-pools',
|
||||
data=jsonutils.dumps(data, sort_keys=True))
|
||||
data=jsonutils.dumps(data, sort_keys=True),
|
||||
headers=self.default_headers())
|
||||
|
||||
def test_create_ip_pool_no_ranges_with_gateway(self):
|
||||
pool = self._mocked_pool()
|
||||
|
@ -794,7 +820,8 @@ class IpPoolTestCase(nsxlib_testcase.NsxClientTestCase):
|
|||
test_client.assert_json_call(
|
||||
'post', pool,
|
||||
'https://1.2.3.4/api/v1/pools/ip-pools',
|
||||
data=jsonutils.dumps(data, sort_keys=True))
|
||||
data=jsonutils.dumps(data, sort_keys=True),
|
||||
headers=self.default_headers())
|
||||
|
||||
def test_create_ip_pool_no_ranges_no_gateway(self):
|
||||
pool = self._mocked_pool()
|
||||
|
@ -812,7 +839,8 @@ class IpPoolTestCase(nsxlib_testcase.NsxClientTestCase):
|
|||
test_client.assert_json_call(
|
||||
'post', pool,
|
||||
'https://1.2.3.4/api/v1/pools/ip-pools',
|
||||
data=jsonutils.dumps(data, sort_keys=True))
|
||||
data=jsonutils.dumps(data, sort_keys=True),
|
||||
headers=self.default_headers())
|
||||
|
||||
def test_create_ip_pool_no_cidr(self):
|
||||
pool = self._mocked_pool()
|
||||
|
@ -844,7 +872,8 @@ class IpPoolTestCase(nsxlib_testcase.NsxClientTestCase):
|
|||
test_client.assert_json_call(
|
||||
'put', pool,
|
||||
'https://1.2.3.4/api/v1/pools/ip-pools/%s' % uuid,
|
||||
data=jsonutils.dumps(fake_ip_pool, sort_keys=True))
|
||||
data=jsonutils.dumps(fake_ip_pool, sort_keys=True),
|
||||
headers=self.default_headers())
|
||||
|
||||
def test_update_ip_pool_gateway(self):
|
||||
fake_ip_pool = test_constants.FAKE_IP_POOL.copy()
|
||||
|
@ -860,7 +889,8 @@ class IpPoolTestCase(nsxlib_testcase.NsxClientTestCase):
|
|||
test_client.assert_json_call(
|
||||
'put', pool,
|
||||
'https://1.2.3.4/api/v1/pools/ip-pools/%s' % uuid,
|
||||
data=jsonutils.dumps(fake_ip_pool, sort_keys=True))
|
||||
data=jsonutils.dumps(fake_ip_pool, sort_keys=True),
|
||||
headers=self.default_headers())
|
||||
|
||||
def test_update_ip_pool_delete_gateway(self):
|
||||
fake_ip_pool = test_constants.FAKE_IP_POOL.copy()
|
||||
|
@ -875,7 +905,8 @@ class IpPoolTestCase(nsxlib_testcase.NsxClientTestCase):
|
|||
test_client.assert_json_call(
|
||||
'put', pool,
|
||||
'https://1.2.3.4/api/v1/pools/ip-pools/%s' % uuid,
|
||||
data=jsonutils.dumps(fake_ip_pool, sort_keys=True))
|
||||
data=jsonutils.dumps(fake_ip_pool, sort_keys=True),
|
||||
headers=self.default_headers())
|
||||
|
||||
def test_get_ip_pool(self):
|
||||
"""Test getting a router port by router id"""
|
||||
|
@ -891,7 +922,8 @@ class IpPoolTestCase(nsxlib_testcase.NsxClientTestCase):
|
|||
self.assertEqual(fake_ip_pool, result)
|
||||
test_client.assert_json_call(
|
||||
'get', pool,
|
||||
'https://1.2.3.4/api/v1/pools/ip-pools/%s' % uuid)
|
||||
'https://1.2.3.4/api/v1/pools/ip-pools/%s' % uuid,
|
||||
headers=self.default_headers())
|
||||
|
||||
def test_delete_ip_pool(self):
|
||||
"""Test deleting router port"""
|
||||
|
@ -901,7 +933,8 @@ class IpPoolTestCase(nsxlib_testcase.NsxClientTestCase):
|
|||
pool.delete(uuid)
|
||||
test_client.assert_json_call(
|
||||
'delete', pool,
|
||||
'https://1.2.3.4/api/v1/pools/ip-pools/%s' % uuid)
|
||||
'https://1.2.3.4/api/v1/pools/ip-pools/%s' % uuid,
|
||||
headers=self.default_headers())
|
||||
|
||||
def test_allocate_ip_from_pool(self):
|
||||
pool = self._mocked_pool()
|
||||
|
@ -914,7 +947,8 @@ class IpPoolTestCase(nsxlib_testcase.NsxClientTestCase):
|
|||
test_client.assert_json_call(
|
||||
'post', pool,
|
||||
'https://1.2.3.4/api/v1/pools/ip-pools/%s?action=ALLOCATE' % uuid,
|
||||
data=jsonutils.dumps(data, sort_keys=True))
|
||||
data=jsonutils.dumps(data, sort_keys=True),
|
||||
headers=self.default_headers())
|
||||
|
||||
def test_release_ip_to_pool(self):
|
||||
pool = self._mocked_pool()
|
||||
|
@ -927,7 +961,8 @@ class IpPoolTestCase(nsxlib_testcase.NsxClientTestCase):
|
|||
test_client.assert_json_call(
|
||||
'post', pool,
|
||||
'https://1.2.3.4/api/v1/pools/ip-pools/%s?action=RELEASE' % uuid,
|
||||
data=jsonutils.dumps(data, sort_keys=True))
|
||||
data=jsonutils.dumps(data, sort_keys=True),
|
||||
headers=self.default_headers())
|
||||
|
||||
def test_get_ip_pool_allocations(self):
|
||||
"""Test getting a router port by router id"""
|
||||
|
@ -943,7 +978,8 @@ class IpPoolTestCase(nsxlib_testcase.NsxClientTestCase):
|
|||
self.assertEqual(fake_ip_pool, result)
|
||||
test_client.assert_json_call(
|
||||
'get', pool,
|
||||
'https://1.2.3.4/api/v1/pools/ip-pools/%s/allocations' % uuid)
|
||||
'https://1.2.3.4/api/v1/pools/ip-pools/%s/allocations' % uuid,
|
||||
headers=self.default_headers())
|
||||
|
||||
|
||||
class TestNsxSearch(nsxlib_testcase.NsxClientTestCase):
|
||||
|
|
|
@ -19,6 +19,7 @@ import copy
|
|||
import datetime
|
||||
import itertools
|
||||
import logging
|
||||
import re
|
||||
|
||||
import eventlet
|
||||
from eventlet import greenpool
|
||||
|
@ -105,8 +106,8 @@ class TimeoutSession(requests.Session):
|
|||
def request(self, *args, **kwargs):
|
||||
if 'timeout' not in kwargs:
|
||||
kwargs['timeout'] = (self.timeout, self.read_timeout)
|
||||
|
||||
if not self._cert_provider:
|
||||
skip_cert = kwargs.pop('skip_cert', False)
|
||||
if not self._cert_provider or skip_cert:
|
||||
return super(TimeoutSession, self).request(*args, **kwargs)
|
||||
|
||||
if self.cert is not None:
|
||||
|
@ -145,6 +146,12 @@ class NSXRequestsHTTPProvider(AbstractHTTPProvider):
|
|||
using requests.Session() as the underlying connection.
|
||||
"""
|
||||
|
||||
SESSION_CREATE_URL = '/api/session/create'
|
||||
COOKIE_FIELD = 'Cookie'
|
||||
SET_COOKIE_FIELD = 'Set-Cookie'
|
||||
XSRF_TOKEN = 'X-XSRF-TOKEN'
|
||||
JSESSIONID = 'JSESSIONID'
|
||||
|
||||
@property
|
||||
def provider_id(self):
|
||||
return "%s-%s" % (requests.__title__, requests.__version__)
|
||||
|
@ -152,7 +159,8 @@ class NSXRequestsHTTPProvider(AbstractHTTPProvider):
|
|||
def validate_connection(self, cluster_api, endpoint, conn):
|
||||
client = nsx_client.NSX3Client(
|
||||
conn, url_prefix=endpoint.provider.url,
|
||||
url_path_base=cluster_api.nsxlib_config.url_base)
|
||||
url_path_base=cluster_api.nsxlib_config.url_base,
|
||||
default_headers=conn.default_headers)
|
||||
keepalive_section = cluster_api.nsxlib_config.keepalive_section
|
||||
result = client.get(keepalive_section, silent=True)
|
||||
# If keeplive section returns a list, it is assumed to be non-empty
|
||||
|
@ -189,11 +197,45 @@ class NSXRequestsHTTPProvider(AbstractHTTPProvider):
|
|||
session.mount('http://', adapter)
|
||||
session.mount('https://', adapter)
|
||||
|
||||
self.get_default_headers(session, provider)
|
||||
|
||||
return session
|
||||
|
||||
def is_connection_exception(self, exception):
|
||||
return isinstance(exception, requests_exceptions.ConnectionError)
|
||||
|
||||
def get_default_headers(self, session, provider):
|
||||
"""Get the default headers that should be added to future requests"""
|
||||
session.default_headers = {}
|
||||
|
||||
# Perform the initial session create and get the relevant jsessionid &
|
||||
# X-XSRF-TOKEN for future requests
|
||||
req_data = 'j_username=%s&j_password=%s' % (provider.username,
|
||||
provider.password)
|
||||
req_headers = {'Accept': 'application/json',
|
||||
'Content-Type': 'application/x-www-form-urlencoded'}
|
||||
# Cannot use the certificate at this stage, because it is used for
|
||||
# the certificate generation
|
||||
resp = session.request('post', provider.url + self.SESSION_CREATE_URL,
|
||||
data=req_data, headers=req_headers,
|
||||
skip_cert=True)
|
||||
if resp.status_code != 200:
|
||||
LOG.error("Session create failed for endpoint %s", provider.url)
|
||||
# this will later cause the endpoint to be Down
|
||||
else:
|
||||
for header_name in resp.headers:
|
||||
if self.SET_COOKIE_FIELD.lower() == header_name.lower():
|
||||
m = re.match('%s=.*?\;' % self.JSESSIONID,
|
||||
resp.headers[header_name])
|
||||
if m:
|
||||
session.default_headers[self.COOKIE_FIELD] = m.group()
|
||||
if self.XSRF_TOKEN.lower() == header_name.lower():
|
||||
session.default_headers[self.XSRF_TOKEN] = resp.headers[
|
||||
header_name]
|
||||
LOG.info("Session create succeeded for endpoint %(url)s with "
|
||||
"headers %(hdr)s",
|
||||
{'url': provider.url, 'hdr': session.default_headers})
|
||||
|
||||
|
||||
class ClusterHealth(object):
|
||||
"""Indicator of overall cluster health.
|
||||
|
@ -494,6 +536,11 @@ class ClusteredAPI(object):
|
|||
try:
|
||||
LOG.debug("API cluster proxy %s %s to %s",
|
||||
proxy_for.upper(), uri, url)
|
||||
# Add the connection default headers
|
||||
if conn.default_headers:
|
||||
kwargs['headers'] = kwargs.get('headers', {})
|
||||
kwargs['headers'].update(conn.default_headers)
|
||||
|
||||
# call the actual connection method to do the
|
||||
# http request/response over the wire
|
||||
response = do_request(url, *args, **kwargs)
|
||||
|
|
Loading…
Reference in New Issue