Commit b3bcb684 authored by Rafael Monnerat's avatar Rafael Monnerat

WIP: re6st-registry: Start to Refactor integration.

parent 8080fab7
......@@ -18,26 +18,6 @@ logging.basicConfig(level=logging.INFO)
logging.trace = logging.debug
class iterRoutes(object):
_waiting = True
def __new__(cls, control_socket, network):
self = object.__new__(cls)
c = ctl.Babel(control_socket, self, network)
c.request_dump()
while self._waiting:
args = {}, {}, ()
c.select(*args)
utils.select(*args)
return (prefix
for neigh_routes in c.neighbours.itervalues()
for prefix in neigh_routes[1]
if prefix)
def babel_dump(self):
self._waiting = False
def loadJsonFile(path):
if os.path.exists(path):
with open(path, 'r') as f:
......@@ -58,8 +38,9 @@ def readFile(path):
return ''
def getDb(db_path):
db = sqlite3.connect(db_path, isolation_level=None,
check_same_thread=False)
db = sqlite3.connect(db_path,
isolation_level=None,
check_same_thread=False)
db.text_factory = str
return db.cursor()
......@@ -68,7 +49,7 @@ def bang(args):
computer_guid = args['computer_id']
partition_id = args['partition_id']
slap = slapos.slap.slap()
# Redeploy instance to update published information
slap.initializeConnection(args['server_url'], args['key_file'],
args['cert_file'])
......@@ -77,14 +58,14 @@ 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)
registry_url = args['registry_url']
base_token_path = args['token_base_path']
path_list = [x for x in os.listdir(base_token_path) if x.endswith('.add')]
log.info("Searching tokens to add at %s and found %s." % (base_token_path, path_list))
if not path_list:
log.info("No new token to add. Exiting...")
return
......@@ -95,22 +76,24 @@ def requestAddToken(args, can_bang=True):
for reference_key in path_list:
request_file = os.path.join(base_token_path, reference_key)
token = readFile(request_file)
log.info("Including token %s for %s" % (token, reference_key))
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)
result = client.requestAddToken(email, token)
except Exception:
log.debug('Request add token fail for %s... \n %s' % (request_file,
log.info('Request add token fail for %s... \n %s' % (request_file,
traceback.format_exc()))
continue
if result and result == token:
# update information
log.info("New token added for slave instance %s. Updating file status..." %
reference)
writeFile(os.path.join(base_token_path, '%s.status' % reference),
'TOKEN_ADDED')
status_file = os.path.join(base_token_path, '%s.status' % reference)
writeFile(status_file, 'TOKEN_ADDED')
os.unlink(request_file)
call_bang = True
else:
......@@ -161,78 +144,41 @@ def requestRemoveToken(args):
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:
if revokeByMail(args['registry_url'],
'%s@slapos' % reference.lower(),
args['db']):
os.unlink(os.path.join(base_token_path, reference_key))
log.info("Certificate revoked for slave instance %s." % reference)
return
log.info("Failed to revoke email for %s" % reference)
def dumpIPv6Network(slave_reference, db, network, ipv6_file):
email = '%s@slapos' % slave_reference.lower()
try:
cert_string, = db.execute("SELECT cert FROM cert WHERE email = ?",
(email,)).next()
except StopIteration:
# Certificate was not generated yet !!!
pass
# ipv6, ipv6_prefix, ipv6_changed = dumpIPv6Network(slave_reference, db, network, ipv6_file)
# For each email SOFTINT-xxx@slapos a status should be created probably. How to deal with legacy?
def dumpIPv6Network(slave_reference, client, ipv6_file):
email = '%s@slapos' % slave_reference.lower()
try:
if cert_string:
cert = crypto.load_certificate(crypto.FILETYPE_PEM, cert_string)
cn = x509.subnetFromCert(cert)
subnet = network + utils.binFromSubnet(cn)
ipv6 = utils.ipFromBin(subnet)
ipv6_prefix = client.getIPv6Prefix(str(email))
ipv6 = client.getIPv6Address(str(email))
log.info(ipv6)
changed = readFile(ipv6_file) != ipv6
writeFile(ipv6_file, ipv6)
return ipv6, utils.binFromSubnet(cn), changed
return ipv6, ipv6_prefix, changed
except Exception:
log.debug('XXX for %s... \n %s' % (slave_reference,
log.info('XXX for %s... \n %s' % (slave_reference,
traceback.format_exc()))
def sendto(sock, prefix, code):
return sock.sendto("%s\0%c" % (prefix, code), ('::1', tunnel.PORT))
def recv(sock, code):
def dumpIPv4Network(ipv6_prefix, network, ipv4_file, client, peer_prefix_list):
try:
prefix, msg = sock.recv(1<<16).split('\0', 1)
int(prefix, 2)
except ValueError:
pass
else:
if msg and ord(msg[0]) == code:
return prefix, msg[1:]
return None, None
def dumpIPv4Network(ipv6_prefix, network, ipv4_file, sock, peer_prefix_list):
try:
if ipv6_prefix == "00000000000000000000000000000000":
if int(ipv6_prefix) == 0:
# workarround to ignore the first node
ipv4 = "0.0.0.0"
changed = readFile(ipv4_file) != ipv4
......@@ -241,32 +187,22 @@ def dumpIPv4Network(ipv6_prefix, network, ipv4_file, sock, peer_prefix_list):
peers = []
log.info(ipv6_prefix)
log.info(peer_prefix_list)
peer_list = [prefix for prefix in peer_prefix_list if prefix == ipv6_prefix ]
if len(peer_list) == 0:
raise ValueError("Unable to find such prefix on database")
peer = peer_list[0]
log.info("Unable to find such prefix on database")
ipv4 = "0.0.0.0"
sendto(sock, peer, 1)
s = sock,
timeout = 15
end = timeout + time.time()
else:
peer = peer_list[0]
while select.select(s, (), (), timeout)[0]:
prefix, msg = recv(sock, 1)
if prefix == peer:
break
ipv4 = client.getIPv4Information(peer)
if ipv4 is None:
ipv4 = "0.0.0.0"
timeout = max(0, end - time.time())
else:
logging.info("Timeout while querying address for %s/%s", int(peer, 2), len(peer))
msg = ""
if "," in msg:
ipv4 = msg.split(',')[0]
else:
ipv4 = "0.0.0.0"
changed = readFile(ipv4_file) != ipv4
writeFile(ipv4_file, ipv4)
return ipv4, changed
......@@ -275,6 +211,12 @@ def dumpIPv4Network(ipv6_prefix, network, ipv4_file, sock, peer_prefix_list):
traceback.format_exc()))
return "0.0.0.0", False
def getPeerPrefixList(network):
return [prefix for prefix in
ctl.iterRoutes("/var/run/re6stnet/babeld.sock", network)]
def checkService(args, can_bang=True):
base_token_path = args['token_base_path']
token_dict = loadJsonFile(args['token_json'])
......@@ -288,18 +230,19 @@ def checkService(args, can_bang=True):
computer_guid = args['computer_id']
partition_id = args['partition_id']
slap = slapos.slap.slap()
client = registry.RegistryClient(args['registry_url'])
ca = client.getCa()
network = x509.networkFromCa(crypto.load_certificate(crypto.FILETYPE_PEM, ca))
network = client.getNetworkBin()
sock = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM)
peer_prefix_list = [prefix for prefix in
iterRoutes("/var/run/re6stnet/babeld.sock", network)]
peer_prefix_list = getPeerPrefixList(network)
# Check token status
for slave_reference, token in token_dict.iteritems():
log.info("%s %s" % (slave_reference, token))
status_file = os.path.join(base_token_path, '%s.status' % slave_reference)
ipv6_file = os.path.join(base_token_path, '%s.ipv6' % slave_reference)
ipv4_file = os.path.join(base_token_path, '%s.ipv4' % slave_reference)
......@@ -308,11 +251,16 @@ def checkService(args, can_bang=True):
log.info("Token %s dont exist yet." % status_file)
continue
# Better check directly on registry the state
# if Token exist on the table or not.
msg = readFile(status_file)
log.info("Token %s has %s State." % (status_file, msg))
if msg == 'TOKEN_USED':
log.info("Dumping ipv6...")
ipv6, ipv6_prefix, ipv6_changed = dumpIPv6Network(slave_reference, db, network, ipv6_file)
ipv6, ipv6_prefix, ipv6_changed = dumpIPv6Network(slave_reference, client, ipv6_file)
log.info("%s, IPV6 = %s, IPV6_PREFIX = %s" % (slave_reference, ipv6, ipv6_prefix))
_, ipv4_changed = dumpIPv4Network(ipv6_prefix, network, ipv4_file, sock, peer_prefix_list)
if ipv4_changed or ipv6_changed:
......
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