Commit 52b21bd6 authored by Thomas Gambier's avatar Thomas Gambier 🚴🏼

slapos.cookbook: fix re6st token manager

We need to revoke the certificate in addition to remove the token.

See merge request !1724
parent f834a06f
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import logging import logging
import json import json
import os
import time import time
import slapos import slapos
import traceback from pathlib import Path
import logging from re6st import registry
from re6st import registry
log = logging.getLogger('SLAPOS-RE6STNET') log = logging.getLogger('SLAPOS-RE6STNET')
logging.basicConfig(level=logging.INFO) logging.basicConfig(
format='%(asctime)s %(levelname)-8s %(message)s',
logging.trace = logging.debug level=logging.INFO,
datefmt='%Y-%m-%d %H:%M:%S')
def loadJsonFile(path): def loadJsonFile(path):
if os.path.exists(path): if path.exists():
with open(path, 'r') as f: with open(path, 'r') as f:
return json.load(f) return json.load(f)
return {} return {}
...@@ -24,7 +23,7 @@ def writeFile(path, data): ...@@ -24,7 +23,7 @@ def writeFile(path, data):
f.write(data) f.write(data)
def readFile(path): def readFile(path):
if os.path.exists(path): if path.exists():
with open(path, 'r') as f: with open(path, 'r') as f:
content = f.read() content = f.read()
return content return content
...@@ -45,77 +44,81 @@ def getComputerPartition(master_url, key_file, cert_file, ...@@ -45,77 +44,81 @@ def getComputerPartition(master_url, key_file, cert_file,
def requestAddToken(client, token_base_path): def requestAddToken(client, token_base_path):
time.sleep(3) time.sleep(3)
path_list = [x for x in os.listdir(token_base_path) if x.endswith('.add')] path_list = [x for x in token_base_path.iterdir() if x.suffix == '.add']
log.info("Searching tokens to add at %s and found %s." % (token_base_path, path_list)) log.info("Searching tokens to add at %s and found %s.", token_base_path, path_list)
if not path_list: if not path_list:
log.info("No new token to add. Exiting...") log.info("No new token to add. Exiting...")
return return
for reference_key in path_list: for reference_key in path_list:
request_file = os.path.join(token_base_path, reference_key) request_file = token_base_path / reference_key
token = readFile(request_file) token = readFile(request_file)
log.info("Including token %s for %s" % (token, reference_key)) log.info("Including token %s for %s", token, reference_key)
if token : if token :
reference = reference_key.split('.')[0] reference = reference_key.stem
# email is unique as reference is also unique # email is unique as reference is also unique
email = '%s@slapos' % reference.lower() email = '%s@slapos' % reference.lower()
try: try:
result = client.addToken(email, token) result = client.addToken(email, token)
except Exception: except Exception:
log.info('Request add token fail for %s... \n %s' % (request_file, log.exception('Request add token fail for %s...', request_file)
traceback.format_exc()))
continue continue
if result in (token, None): if result in (token, None):
# update information # update information
log.info("New token added for slave instance %s. Updating file status..." % log.info("New token added for slave instance %s. Updating file status...",
reference) reference)
status_file = os.path.join(token_base_path, '%s.status' % reference) status_file = (token_base_path / reference).with_suffix('.status')
updateFile(status_file, 'TOKEN_ADDED') updateFile(status_file, 'TOKEN_ADDED')
os.unlink(request_file) request_file.unlink()
else: else:
log.debug('Bad token. Request add token fail for %s...' % request_file) log.debug('Bad token. Request add token fail for %s...', request_file)
def requestRemoveToken(client, token_base_path): def requestRemoveToken(client, token_base_path):
path_list = [x for x in os.listdir(token_base_path) if x.endswith('.remove')] path_list = [x for x in token_base_path.iterdir() if x.suffix == '.remove']
if not path_list: if not path_list:
log.info("No token to delete. Exiting...") log.info("No token to delete. Exiting...")
return return
for reference_key in path_list: for reference_key in path_list:
request_file = os.path.join(token_base_path, reference_key) request_file = token_base_path / reference_key
token = readFile(request_file) token = readFile(request_file)
if token : if token :
reference = reference_key.split('.')[0] reference = reference_key.stem
try: try:
result = client.deleteToken(token) result = client.deleteToken(token)
except Exception: except Exception:
log.debug('Request delete token fail for %s... \n %s' % (request_file, log.exception('Request delete token fail for %s...', request_file)
traceback.format_exc()))
continue continue
else:
# certificate is invalidated, it will be revoked
writeFile(os.path.join(token_base_path, '%s.revoke' % reference), '')
if result in (True, 'True'): if not client.isToken(str(token)):
# update information # Token has been destroyed or is already used, we can proceed to revoke the certificate
log.info("Token deleted for slave instance %s. Clean up file status..." % email = '%s@slapos' % reference.lower()
try:
cn = client.getNodePrefix(str(email))
except Exception:
log.exception('getNodePrefix for email %s failed', email)
continue
if cn:
try:
client.revoke(cn)
except Exception:
log.exception('Revoke cert with cn %s failed...', cn)
continue
log.info("Token deleted for slave instance %s. Clean up file status...",
reference) reference)
request_file.unlink()
if result in ['True', 'False']: status_file = request_file.with_suffix('.status')
os.unlink(request_file) status_file.unlink()
status_file = os.path.join(token_base_path, '%s.status' % reference) ipv6_file = request_file.with_suffix('.ipv6')
if os.path.exists(status_file): ipv6_file.unlink(missing_ok=True)
os.unlink(status_file)
ipv6_file = os.path.join(token_base_path, '%s.ipv6' % reference)
if os.path.exists(ipv6_file):
os.unlink(ipv6_file)
else: else:
log.debug('Bad token. Request remove token fail for %s...' % request_file) log.error('Bad token. Request remove token fail for %s...', request_file)
def checkService(client, token_base_path, token_json, computer_partition): def checkService(client, token_base_path, token_json, computer_partition):
token_dict = loadJsonFile(token_json) token_dict = loadJsonFile(token_json)
...@@ -125,9 +128,9 @@ def checkService(client, token_base_path, token_json, computer_partition): ...@@ -125,9 +128,9 @@ def checkService(client, token_base_path, token_json, computer_partition):
# Check token status # Check token status
for slave_reference, token in token_dict.items(): for slave_reference, token in token_dict.items():
log.info("%s %s" % (slave_reference, token)) log.info("%s %s", slave_reference, token)
status_file = os.path.join(token_base_path, '%s.status' % slave_reference) status_file = (token_base_path / slave_reference).with_suffix('.status')
if not os.path.exists(status_file): if not status_file.exists():
# This token is not added yet! # This token is not added yet!
log.info("Token %s dont exist yet." % status_file) log.info("Token %s dont exist yet." % status_file)
continue continue
...@@ -135,10 +138,10 @@ def checkService(client, token_base_path, token_json, computer_partition): ...@@ -135,10 +138,10 @@ def checkService(client, token_base_path, token_json, computer_partition):
if not client.isToken(str(token)): if not client.isToken(str(token)):
# Token is used to register client # Token is used to register client
updateFile(status_file, 'TOKEN_USED') updateFile(status_file, 'TOKEN_USED')
log.info("Token status of %s updated to 'used'." % slave_reference) log.info("Token status of %s updated to 'used'.", slave_reference)
status = readFile(status_file) status = readFile(status_file)
log.info("Token %s has %s State." % (status_file, status)) log.info("Token %s has %s State.", status_file, status)
ipv6 = "::" ipv6 = "::"
ipv4 = "0.0.0.0" ipv4 = "0.0.0.0"
...@@ -153,20 +156,17 @@ def checkService(client, token_base_path, token_json, computer_partition): ...@@ -153,20 +156,17 @@ def checkService(client, token_base_path, token_json, computer_partition):
try: try:
ipv6 = client.getIPv6Address(str(email)).decode() ipv6 = client.getIPv6Address(str(email)).decode()
except Exception: except Exception:
log.info('Error for dump ipv6 for %s... \n %s' % (slave_reference, log.exception('Error for dump ipv6 for %s...', slave_reference)
traceback.format_exc())) log.info("%s, IPV6 = %s", slave_reference, ipv6)
log.info("%s, IPV6 = %s" % (slave_reference, ipv6))
try: try:
ipv4 = client.getIPv4Information(str(email)).decode() or "0.0.0.0" ipv4 = client.getIPv4Information(str(email)).decode() or "0.0.0.0"
except Exception: except Exception:
log.info('Error for dump ipv4 for %s... \n %s' % (slave_reference, log.exception('Error for dump ipv4 for %s...', slave_reference)
traceback.format_exc()))
log.info("%s, IPV4 = %s" % (slave_reference, ipv4)) log.info("%s, IPV4 = %s" % (slave_reference, ipv4))
try: try:
log.info("Update parameters for %s" % slave_reference) log.info("Update parameters for %s", slave_reference)
# Normalise the values as simple strings to be on the same format that # Normalise the values as simple strings to be on the same format that
# the values which come from master. # the values which come from master.
...@@ -176,13 +176,13 @@ def checkService(client, token_base_path, token_json, computer_partition): ...@@ -176,13 +176,13 @@ def checkService(client, token_base_path, token_json, computer_partition):
'ipv4': str(ipv4)}, 'ipv4': str(ipv4)},
slave_reference) slave_reference)
except Exception: except Exception:
log.fatal("Error while sending slave %s informations: %s", log.exception("Error while sending slave %s information",
slave_reference, traceback.format_exc()) slave_reference)
def manage(registry_url, token_base_path, token_json, def manage(registry_url, token_base_path, token_json,
computer_dict, can_bang=True): computer_dict, can_bang=True):
token_base_path = Path(token_base_path)
client = registry.RegistryClient(registry_url) client = registry.RegistryClient(registry_url)
log.info("ADD TOKEN") log.info("ADD TOKEN")
...@@ -197,5 +197,5 @@ def manage(registry_url, token_base_path, token_json, ...@@ -197,5 +197,5 @@ def manage(registry_url, token_base_path, token_json,
log.info("Update Services") log.info("Update Services")
# check status of all token # check status of all token
checkService(client, token_base_path, token_json, computer_partition) checkService(client, token_base_path, Path(token_json), computer_partition)
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