Commit ef936b2a authored by Alain Takoudjou's avatar Alain Takoudjou

re6st recipe: Add script to revoke certificate when instance is destroyed

parent f45fa313
......@@ -96,7 +96,7 @@ class Recipe(GenericBaseRecipe):
if not reference in token_dict:
# we generate new token
number = reference.split('-')[1]
new_token = number + ''.join(random.sample(string.ascii_lowercase, 15))
new_token = number + ''.join(random.sample(string.ascii_lowercase, 20))
token_dict[reference] = new_token
to_add_dict[reference] = new_token
......@@ -127,6 +127,17 @@ class Recipe(GenericBaseRecipe):
return content
return ''
def genHash(self, length):
hash_path = os.path.join(self.options['conf-dir'], '%s-hash' % length)
if not os.path.exists(hash_path):
pool = string.letters + string.digits
hash_string = ''.join(random.choice(pool) for i in xrange(length))
self.writeFile(hash_path, hash_string)
else:
hash_string = self.readFile(hash_path)
return hash_string
def install(self):
path_list = []
token_save_path = os.path.join(self.options['conf-dir'], 'token.json')
......@@ -156,7 +167,7 @@ class Recipe(GenericBaseRecipe):
path = os.path.join(token_list_path, '%s.remove' % reference)
if not os.path.exists(path):
self.createFile(path, rm_token_dict[reference])
# remove request add file if exists
# remove request add token if exists
add_path = os.path.join(token_list_path, '%s.add' % reference)
if os.path.exists(add_path):
os.unlink(add_path)
......@@ -191,6 +202,12 @@ class Recipe(GenericBaseRecipe):
)
path_list.append(request_check)
revoke_check = self.createPythonScript(
self.options['revoke-service-wrapper'].strip(),
'%s.re6stnet.requestRevoqueCertificate' % __name__, service_dict
)
path_list.append(revoke_check)
# Send connection parameters of slave instances
if token_dict:
self.slap.initializeConnection(self.server_url, self.key_file,
......@@ -211,7 +228,7 @@ class Recipe(GenericBaseRecipe):
computer_partition.setConnectionDict(
{'token':token, '1_info':msg},
slave_reference)
except:
except Exception:
self.logger.fatal("Error while sending slave %s informations: %s",
slave_reference, traceback.format_exc())
......
......@@ -5,8 +5,10 @@ import os
import time
import sqlite3
import slapos
import traceback
from re6st import registry
from re6st import registry, x509
from OpenSSL import crypto
log = logging.getLogger('SLAPOS-RE6STNET')
logging.basicConfig(level=logging.DEBUG)
......@@ -50,6 +52,7 @@ def bang(args):
partition.bang(message='Published parameters changed!')
log.info("Bang with message 'parameters changed'...")
def requestAddToken(args, can_bang=True):
time.sleep(3)
......@@ -69,12 +72,13 @@ def requestAddToken(args, can_bang=True):
token = readFile(request_file)
if token :
reference = reference_key.split('.')[0]
# email is unique as reference is also unique
email = '%s@slapos' % reference.lower()
try:
result = client.requestAddToken(token, email)
except Exception, e:
except Exception:
log.debug('Request add token fail for %s... \n %s' % (request_file,
str(e)))
traceback.format_exc()))
continue
if result and result == token:
# update information
......@@ -97,7 +101,7 @@ def requestRemoveToken(args):
if not path_list:
log.info("No token to delete. Exiting...")
return
client = registry.RegistryClient(args['registry_url'])
for reference_key in path_list:
request_file = os.path.join(base_token_path, reference_key)
......@@ -106,23 +110,58 @@ def requestRemoveToken(args):
reference = reference_key.split('.')[0]
try:
result = client.requestDeleteToken(token)
except Exception, e:
except Exception:
log.debug('Request delete token fail for %s... \n %s' % (request_file,
str(e)))
traceback.format_exc()))
continue
else:
# certificate is invalidated, it will be revoked
writeFile(os.path.join(base_token_path, '%s.revoke' % reference), '')
if result == 'True':
# update information
log.info("Token deleted for slave instance %s. Clean up file status..." %
reference)
if result in ['True', 'False']:
os.unlink(request_file)
status_file = os.path.join(base_token_path, '%s.status' % reference)
if os.path.exists(status_file):
os.unlink(status_file)
else:
log.debug('Request delete token fail for %s...' % request_file)
else:
log.debug('Bad token. Request add token fail for %s...' % request_file)
def requestRevoqueCertificate(args):
base_token_path = args['token_base_path']
db = getDb(args['db'])
path_list = [x for x in os.listdir(base_token_path) if x.endswith('.revoke')]
client = registry.RegistryClient(args['registry_url'])
for reference_key in path_list:
reference = reference_key.split('.')[0]
# XXX - email is always unique
email = '%s@slapos' % reference.lower()
cert_string = ''
try:
cert_string, = db.execute("SELECT cert FROM cert WHERE email = ?",
(email,)).next()
except StopIteration:
# Certificate was not generated yet !!!
pass
try:
if cert_string:
cert = crypto.load_certificate(crypto.FILETYPE_PEM, cert_string)
cn = x509.subnetFromCert(cert)
result = client.revoke(str(cn))
time.sleep(2)
except Exception:
log.debug('Request revoke certificate fail for %s... \n %s' % (reference,
traceback.format_exc()))
continue
else:
os.unlink(os.path.join(base_token_path, reference_key))
log.info("Certificate revoked for slave instance %s." % reference)
def checkService(args, can_bang=True):
base_token_path = args['token_base_path']
token_dict = loadJsonFile(args['token_json'])
......@@ -164,7 +203,7 @@ def checkService(args, can_bang=True):
time.sleep(1)
writeFile(status_file, 'TOKEN_USED')
log.info("Token status of %s updated to 'used'." % slave_reference)
except IOError, e:
except IOError:
# XXX- this file should always exists
log.debug('Error when writing in file %s. Clould not update status of %s...' %
(status_file, slave_reference))
......@@ -181,3 +220,4 @@ def manage(args):
# check status of all token
checkService(args)
......@@ -36,6 +36,7 @@ class Re6stnetTest(unittest.TestCase):
'manager-wrapper': os.path.join(self.base_dir, 'manager_wrapper'),
'drop-service-wrapper': os.path.join(self.base_dir, 'drop_wrapper'),
'check-service-wrapper': os.path.join(self.base_dir, 'check_wrapper'),
'revoke-service-wrapper': os.path.join(self.base_dir, 'revoke_wrapper'),
'slave-instance-list': '{}'
}
......@@ -96,7 +97,7 @@ class Re6stnetTest(unittest.TestCase):
with open(path, 'r') as f:
content = f.read()
self.assertIn("@%s" % config_file, content)
def test_generateCertificates(self):
self.options['ipv6-prefix'] = '2001:db8:24::/48'
......@@ -175,6 +176,7 @@ class Re6stnetTest(unittest.TestCase):
self.checkWrapper(os.path.join(self.base_dir, 'manager_wrapper'))
self.checkWrapper(os.path.join(self.base_dir, 'drop_wrapper'))
self.checkWrapper(os.path.join(self.base_dir, 'check_wrapper'))
self.checkWrapper(os.path.join(self.base_dir, 'revoke_wrapper'))
self.checkRegistryWrapper()
# Remove one element
......@@ -218,5 +220,6 @@ class Re6stnetTest(unittest.TestCase):
self.checkWrapper(os.path.join(self.base_dir, 'manager_wrapper'))
self.checkWrapper(os.path.join(self.base_dir, 'drop_wrapper'))
self.checkWrapper(os.path.join(self.base_dir, 'check_wrapper'))
self.checkWrapper(os.path.join(self.base_dir, 'revoke_wrapper'))
self.checkRegistryWrapper()
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment