mirror of
https://github.com/OpenKMIP/PyKMIP.git
synced 2025-07-20 12:34:22 +02:00
Merge pull request #103 from hadesto/dev/hadi/server-failover/feature
Server Failover Feature
This commit is contained in:
commit
3afa0e8124
@ -5,7 +5,7 @@ keyfile=None
|
|||||||
certfile=None
|
certfile=None
|
||||||
cert_reqs=CERT_REQUIRED
|
cert_reqs=CERT_REQUIRED
|
||||||
ssl_version=PROTOCOL_SSLv23
|
ssl_version=PROTOCOL_SSLv23
|
||||||
ca_certs=../demos/certs/server.crt
|
ca_certs=./demos/certs/server.crt
|
||||||
do_handshake_on_connect=True
|
do_handshake_on_connect=True
|
||||||
suppress_ragged_eofs=True
|
suppress_ragged_eofs=True
|
||||||
username=None
|
username=None
|
||||||
@ -15,8 +15,8 @@ timeout=30
|
|||||||
[server]
|
[server]
|
||||||
host=127.0.0.1
|
host=127.0.0.1
|
||||||
port=5696
|
port=5696
|
||||||
keyfile=../demos/certs/server.key
|
keyfile=./demos/certs/server.key
|
||||||
certfile=../demos/certs/server.crt
|
certfile=./demos/certs/server.crt
|
||||||
cert_reqs=CERT_NONE
|
cert_reqs=CERT_NONE
|
||||||
ssl_version=PROTOCOL_SSLv23
|
ssl_version=PROTOCOL_SSLv23
|
||||||
ca_certs=None
|
ca_certs=None
|
||||||
|
@ -76,7 +76,8 @@ CONFIG_FILE = os.path.normpath(os.path.join(FILE_PATH, '../kmipconfig.ini'))
|
|||||||
|
|
||||||
class KMIPProxy(KMIP):
|
class KMIPProxy(KMIP):
|
||||||
|
|
||||||
def __init__(self, host=None, port=None, keyfile=None, certfile=None,
|
def __init__(self, host=None, port=None, keyfile=None,
|
||||||
|
certfile=None,
|
||||||
cert_reqs=None, ssl_version=None, ca_certs=None,
|
cert_reqs=None, ssl_version=None, ca_certs=None,
|
||||||
do_handshake_on_connect=None,
|
do_handshake_on_connect=None,
|
||||||
suppress_ragged_eofs=None,
|
suppress_ragged_eofs=None,
|
||||||
@ -193,7 +194,6 @@ class KMIPProxy(KMIP):
|
|||||||
self.is_authentication_suite_supported(authentication_suite))
|
self.is_authentication_suite_supported(authentication_suite))
|
||||||
|
|
||||||
def open(self):
|
def open(self):
|
||||||
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
|
||||||
|
|
||||||
self.logger.debug("KMIPProxy keyfile: {0}".format(self.keyfile))
|
self.logger.debug("KMIPProxy keyfile: {0}".format(self.keyfile))
|
||||||
self.logger.debug("KMIPProxy certfile: {0}".format(self.certfile))
|
self.logger.debug("KMIPProxy certfile: {0}".format(self.certfile))
|
||||||
@ -209,6 +209,23 @@ class KMIPProxy(KMIP):
|
|||||||
self.logger.debug("KMIPProxy suppress_ragged_eofs: {0}".format(
|
self.logger.debug("KMIPProxy suppress_ragged_eofs: {0}".format(
|
||||||
self.suppress_ragged_eofs))
|
self.suppress_ragged_eofs))
|
||||||
|
|
||||||
|
for host in self.host_list:
|
||||||
|
self.host = host
|
||||||
|
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||||
|
self._create_socket(sock)
|
||||||
|
self.protocol = KMIPProtocol(self.socket)
|
||||||
|
try:
|
||||||
|
self.socket.connect((self.host, self.port))
|
||||||
|
except Exception as e:
|
||||||
|
self.logger.error("An error occurred while connecting to "
|
||||||
|
"appliance " + self.host)
|
||||||
|
self.socket.close()
|
||||||
|
self.socket = None
|
||||||
|
else:
|
||||||
|
return
|
||||||
|
raise e
|
||||||
|
|
||||||
|
def _create_socket(self, sock):
|
||||||
self.socket = ssl.wrap_socket(
|
self.socket = ssl.wrap_socket(
|
||||||
sock,
|
sock,
|
||||||
keyfile=self.keyfile,
|
keyfile=self.keyfile,
|
||||||
@ -218,16 +235,8 @@ class KMIPProxy(KMIP):
|
|||||||
ca_certs=self.ca_certs,
|
ca_certs=self.ca_certs,
|
||||||
do_handshake_on_connect=self.do_handshake_on_connect,
|
do_handshake_on_connect=self.do_handshake_on_connect,
|
||||||
suppress_ragged_eofs=self.suppress_ragged_eofs)
|
suppress_ragged_eofs=self.suppress_ragged_eofs)
|
||||||
self.protocol = KMIPProtocol(self.socket)
|
|
||||||
|
|
||||||
self.socket.settimeout(self.timeout)
|
self.socket.settimeout(self.timeout)
|
||||||
|
|
||||||
try:
|
|
||||||
self.socket.connect((self.host, self.port))
|
|
||||||
except socket.timeout as e:
|
|
||||||
self.logger.error("timeout occurred while connecting to appliance")
|
|
||||||
raise e
|
|
||||||
|
|
||||||
def __del__(self):
|
def __del__(self):
|
||||||
# Close the socket properly, helpful in case close() is not called.
|
# Close the socket properly, helpful in case close() is not called.
|
||||||
self.close()
|
self.close()
|
||||||
@ -881,9 +890,14 @@ class KMIPProxy(KMIP):
|
|||||||
username, password, timeout):
|
username, password, timeout):
|
||||||
conf = ConfigHelper()
|
conf = ConfigHelper()
|
||||||
|
|
||||||
self.host = conf.get_valid_value(
|
# TODO: set this to a host list
|
||||||
|
self.host_list_str = conf.get_valid_value(
|
||||||
host, self.config, 'host', conf.DEFAULT_HOST)
|
host, self.config, 'host', conf.DEFAULT_HOST)
|
||||||
|
|
||||||
|
self.host_list = self._build_host_list(self.host_list_str)
|
||||||
|
|
||||||
|
self.host = self.host_list[0]
|
||||||
|
|
||||||
self.port = int(conf.get_valid_value(
|
self.port = int(conf.get_valid_value(
|
||||||
port, self.config, 'port', conf.DEFAULT_PORT))
|
port, self.config, 'port', conf.DEFAULT_PORT))
|
||||||
|
|
||||||
@ -922,11 +936,27 @@ class KMIPProxy(KMIP):
|
|||||||
self.password = conf.get_valid_value(
|
self.password = conf.get_valid_value(
|
||||||
password, self.config, 'password', conf.DEFAULT_PASSWORD)
|
password, self.config, 'password', conf.DEFAULT_PASSWORD)
|
||||||
|
|
||||||
self.timeout = conf.get_valid_value(
|
self.timeout = int(conf.get_valid_value(
|
||||||
timeout, self.config, 'timeout', conf.DEFAULT_TIMEOUT)
|
timeout, self.config, 'timeout', conf.DEFAULT_TIMEOUT))
|
||||||
if self.timeout < 0:
|
if self.timeout < 0:
|
||||||
self.logger.warning(
|
self.logger.warning(
|
||||||
"Negative timeout value specified, "
|
"Negative timeout value specified, "
|
||||||
"resetting to safe default of {0} seconds".format(
|
"resetting to safe default of {0} seconds".format(
|
||||||
conf.DEFAULT_TIMEOUT))
|
conf.DEFAULT_TIMEOUT))
|
||||||
self.timeout = conf.DEFAULT_TIMEOUT
|
self.timeout = conf.DEFAULT_TIMEOUT
|
||||||
|
|
||||||
|
def _build_host_list(self, host_list_str):
|
||||||
|
'''
|
||||||
|
This internal function takes the host string from the config file
|
||||||
|
and turns it into a list
|
||||||
|
:return: LIST host list
|
||||||
|
'''
|
||||||
|
|
||||||
|
host_list = []
|
||||||
|
if isinstance(host_list_str, str):
|
||||||
|
host_list = host_list_str.replace(' ', '').split(',')
|
||||||
|
else:
|
||||||
|
raise TypeError("Unrecognized variable type provided for host "
|
||||||
|
"list string. 'String' type expected but '" +
|
||||||
|
str(type(host_list_str)) + "' received")
|
||||||
|
return host_list
|
||||||
|
@ -61,6 +61,10 @@ from kmip.services.results import RekeyKeyPairResult
|
|||||||
|
|
||||||
import kmip.core.utils as utils
|
import kmip.core.utils as utils
|
||||||
|
|
||||||
|
import mock
|
||||||
|
|
||||||
|
import socket
|
||||||
|
|
||||||
|
|
||||||
class TestKMIPClient(TestCase):
|
class TestKMIPClient(TestCase):
|
||||||
|
|
||||||
@ -501,6 +505,62 @@ class TestKMIPClient(TestCase):
|
|||||||
self.assertEqual(uid, result.uid)
|
self.assertEqual(uid, result.uid)
|
||||||
self.assertEqual(names, result.names)
|
self.assertEqual(names, result.names)
|
||||||
|
|
||||||
|
def test_host_list_import_string(self):
|
||||||
|
"""
|
||||||
|
This test verifies that the client can process a string with
|
||||||
|
multiple IP addresses specified in it. It also tests that
|
||||||
|
unnecessary spaces are ignored.
|
||||||
|
"""
|
||||||
|
|
||||||
|
host_list_string = '127.0.0.1,127.0.0.3, 127.0.0.5'
|
||||||
|
host_list_expected = ['127.0.0.1', '127.0.0.3', '127.0.0.5']
|
||||||
|
|
||||||
|
self.client._set_variables(host=host_list_string,
|
||||||
|
port=None, keyfile=None, certfile=None,
|
||||||
|
cert_reqs=None, ssl_version=None,
|
||||||
|
ca_certs=None,
|
||||||
|
do_handshake_on_connect=False,
|
||||||
|
suppress_ragged_eofs=None, username=None,
|
||||||
|
password=None, timeout=None)
|
||||||
|
self.assertEqual(host_list_expected, self.client.host_list)
|
||||||
|
|
||||||
|
def test_host_is_invalid_input(self):
|
||||||
|
"""
|
||||||
|
This test verifies that invalid values are not processed when
|
||||||
|
setting the client object parameters
|
||||||
|
"""
|
||||||
|
host = 1337
|
||||||
|
expected_error = TypeError
|
||||||
|
|
||||||
|
kwargs = {'host': host, 'port': None, 'keyfile': None,
|
||||||
|
'certfile': None, 'cert_reqs': None, 'ssl_version': None,
|
||||||
|
'ca_certs': None, 'do_handshake_on_connect': False,
|
||||||
|
'suppress_ragged_eofs': None, 'username': None,
|
||||||
|
'password': None, 'timeout': None}
|
||||||
|
|
||||||
|
self.assertRaises(expected_error, self.client._set_variables,
|
||||||
|
**kwargs)
|
||||||
|
|
||||||
|
@mock.patch('socket.socket.connect')
|
||||||
|
@mock.patch('ssl.SSLSocket.gettimeout')
|
||||||
|
def test_timeout_all_hosts(self, mock_ssl_timeout, mock_connect_return):
|
||||||
|
"""
|
||||||
|
This test verifies that the client will throw an exception if no
|
||||||
|
hosts are available for connection.
|
||||||
|
"""
|
||||||
|
|
||||||
|
mock_ssl_timeout.return_value = 1
|
||||||
|
mock_connect_return.return_value = socket.timeout
|
||||||
|
try:
|
||||||
|
self.client.open()
|
||||||
|
except Exception as e:
|
||||||
|
# TODO: once the exception is properly defined in the
|
||||||
|
# kmip_client.py file this test needs to change to reflect that.
|
||||||
|
self.assertIsInstance(e, Exception)
|
||||||
|
self.client.close()
|
||||||
|
else:
|
||||||
|
self.client.close()
|
||||||
|
|
||||||
|
|
||||||
class TestClientProfileInformation(TestCase):
|
class TestClientProfileInformation(TestCase):
|
||||||
"""
|
"""
|
||||||
|
Loading…
x
Reference in New Issue
Block a user