blob: 0ca7adfa72387e0295436aff82f352a5aa483b12 [file] [log] [blame]
import os
import subprocess
import time
from collections import Mapping
from ccmlib.node import Node
from dtest import debug
# work for cluster started by populate
def new_node(cluster, bootstrap=True, token=None, remote_debug_port='0', data_center=None):
i = len(cluster.nodes) + 1
node = Node('node%s' % i,
cluster,
bootstrap,
('127.0.0.%s' % i, 9160),
('127.0.0.%s' % i, 7000),
str(7000 + i * 100),
remote_debug_port,
token,
binary_interface=('127.0.0.%s' % i, 9042))
cluster.add(node, not bootstrap, data_center=data_center)
return node
def retry_till_success(fun, *args, **kwargs):
timeout = kwargs.pop('timeout', 60)
bypassed_exception = kwargs.pop('bypassed_exception', Exception)
deadline = time.time() + timeout
while True:
try:
return fun(*args, **kwargs)
except bypassed_exception:
if time.time() > deadline:
raise
else:
# brief pause before next attempt
time.sleep(0.25)
def generate_ssl_stores(base_dir, passphrase='cassandra'):
"""
Util for generating ssl stores using java keytool -- nondestructive method if stores already exist this method is
a no-op.
@param base_dir (str) directory where keystore.jks, truststore.jks and ccm_node.cer will be placed
@param passphrase (Optional[str]) currently ccm expects a passphrase of 'cassandra' so it's the default but it can be
overridden for failure testing
@return None
@throws CalledProcessError If the keytool fails during any step
"""
if os.path.exists(os.path.join(base_dir, 'keystore.jks')):
debug("keystores already exists - skipping generation of ssl keystores")
return
debug("generating keystore.jks in [{0}]".format(base_dir))
subprocess.check_call(['keytool', '-genkeypair', '-alias', 'ccm_node', '-keyalg', 'RSA', '-validity', '365',
'-keystore', os.path.join(base_dir, 'keystore.jks'), '-storepass', passphrase,
'-dname', 'cn=Cassandra Node,ou=CCMnode,o=DataStax,c=US', '-keypass', passphrase])
debug("exporting cert from keystore.jks in [{0}]".format(base_dir))
subprocess.check_call(['keytool', '-export', '-rfc', '-alias', 'ccm_node',
'-keystore', os.path.join(base_dir, 'keystore.jks'),
'-file', os.path.join(base_dir, 'ccm_node.cer'), '-storepass', passphrase])
debug("importing cert into truststore.jks in [{0}]".format(base_dir))
subprocess.check_call(['keytool', '-import', '-file', os.path.join(base_dir, 'ccm_node.cer'),
'-alias', 'ccm_node', '-keystore', os.path.join(base_dir, 'truststore.jks'),
'-storepass', passphrase, '-noprompt'])
class ImmutableMapping(Mapping):
"""
Convenience class for when you want an immutable-ish map.
Useful at class level to prevent mutability problems (such as a method altering the class level mutable)
"""
def __init__(self, init_dict):
self._data = init_dict.copy()
def __getitem__(self, key):
return self._data[key]
def __iter__(self):
return iter(self._data)
def __len__(self):
return len(self._data)
def __repr__(self):
return '{cls}({data})'.format(cls=self.__class__.__name__, data=self._data)