#!/usr/bin/env python

from builtins import object

import datetime
from io import BytesIO
import logging
import os
import tempfile
import subprocess
import sys

from cryptography import x509
from cryptography.hazmat.backends import default_backend
import fabric

import secretstore


cluster = 'k0.hswaw.net'
remote_root = '/opt/hscloud'
local_root = os.getenv('hscloud_root')

if local_root is None:
    raise Exception("Please source env.sh")

logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)
logger.addHandler(logging.StreamHandler())


def decrypt(base):
    src = os.path.join(local_root, 'cluster/secrets/cipher', base)
    dst = os.path.join(local_root, 'cluster/secrets/plain', base)
    secretstore.decrypt(src, dst)


class PKI(object):
    def __init__(self):
        self.cacert = os.path.join(local_root, 'cluster/certs/ca.crt')
        self.cakey = os.path.join(local_root, 'cluster/secrets/plain/ca.key')

        if not os.path.exists(self.cakey):
            decrypt('ca.key')

    def sign(self, csr, crt, conf, days=365):
        logger.info('pki: signing {} for {} days'.format(csr, days))
        subprocess.check_call([
            'openssl', 'x509', '-req',
            '-in', csr,
            '-CA', self.cacert,
            '-CAkey', self.cakey,
            '-out', crt,
            '-extensions', 'SAN', '-extfile', conf,
            '-days', str(days),
        ])


class Subject(object):
    hswaw = "Stowarzyszenie Warszawski Hackerspace"
    def __init__(self, o, ou, cn):
        self.c = 'PL'
        self.st = 'Mazowieckie'
        self.l = 'Warszawa'
        self.o = o
        self.ou = ou
        self.cn = cn

    @property
    def parts(self):
        return {
            'C': self.c,
            'ST': self.st,
            'L': self.l,
            'O': self.o,
            'OU': self.ou,
            'CN': self.cn,
        }

    def __str__(self):
        parts = self.parts
        res = []
        for p in ['C', 'ST', 'L', 'O', 'OU', 'CN']:
            res.append('/{}={}'.format(p, parts[p]))
        return ''.join(res)

def _file_exists(c, filename):
    res = c.run('stat "{}"'.format(filename), warn=True, hide=True)
    return res.exited == 0

def openssl_config(san):
    with open(os.path.join(local_root, 'cluster/openssl.cnf'), 'rb') as f:
        config = BytesIO(f.read())

    config.seek(0, 2)
    config.write(b'\n[SAN]\n')
    for s in san:
        config.write('subjectAltName=DNS:{}\n'.format(s).encode())

    f = tempfile.NamedTemporaryFile(delete=False)
    path = f.name
    f.write(config.getvalue())
    f.close()

    return path

def remote_cert(pki, c, fqdn, cert_name, subj, san=[], days=365):
    logger.info("{}/{}: remote cert".format(fqdn, cert_name))

    remote_key = os.path.join(remote_root, '{}.key'.format(cert_name))
    remote_cert = os.path.join(remote_root, '{}.crt'.format(cert_name))
    remote_csr = os.path.join(remote_root, '{}.csr'.format(cert_name))
    remote_config = os.path.join(remote_root, 'openssl.cnf')

    generate_cert = False
    if not _file_exists(c, remote_key):
        logger.info("{}/{}: generating key".format(fqdn, cert_name))
        c.run('openssl genrsa -out "{}" 4096'.format(remote_key), hide=True)
        genereate_cert = True

    b = BytesIO()
    try:
        c.get(local=b, remote=remote_cert)
        cert = x509.load_pem_x509_certificate(b.getvalue(), default_backend())
        delta = cert.not_valid_after - datetime.datetime.now()
        logger.info("{}/{}: existing cert expiry: {}".format(fqdn, cert_name, delta))
        if delta.total_seconds() < 3600 * 24 * 60:
            logger.info("{}/{}: expires soon, regenerating".format(fqdn, cert_name))
            generate_cert = True
    except (FileNotFoundError, ValueError):
        generate_cert = True

    if not generate_cert:
        return False


    local_config = openssl_config(san)
    c.put(local=local_config, remote=remote_config)

    c.run("""
        nix-shell -p openssl --command "openssl req -new -key {remote_key} -out {remote_csr} -subj '{subj}' -config {remote_config} -reqexts SAN"
    """.format(remote_key=remote_key, remote_csr=remote_csr, subj=str(subj), remote_config=remote_config))

    local_csr_f = tempfile.NamedTemporaryFile(delete=False)
    local_csr = local_csr_f.name
    local_csr_f.close()

    local_cert = os.path.join(local_root, 'cluster/certs', '{}-{}.crt'.format(fqdn, cert_name))

    c.get(local=local_csr, remote=remote_csr)

    pki.sign(local_csr, local_cert, local_config, days)

    c.put(local=local_cert, remote=remote_cert)

    os.remove(local_csr)
    os.remove(local_config)

    return True


def shared_cert(pki, c, fqdn, cert_name, subj, san=[], days=365):
    logger.info("{}/{}: shared cert".format(fqdn, cert_name))

    local_key = os.path.join(local_root, 'cluster/secrets/plain', '{}.key'.format(cert_name))
    local_cert = os.path.join(local_root, 'cluster/certs', '{}.crt'.format(cert_name))
    remote_key = os.path.join(remote_root, '{}.key'.format(cert_name))
    remote_cert = os.path.join(remote_root, '{}.crt'.format(cert_name))

    generate_cert = False
    if not os.path.exists(local_key):
        try:
            decrypt('{}.key'.format(cert_name))
        except subprocess.CalledProcessError:
            logger.info("{}/{}: generating key".format(fqdn, cert_name))
            subprocess.check_call([
                'openssl', 'genrsa', '-out', local_key, '4096',
            ])
            generate_cert = True

    if os.path.exists(local_cert):
        with open(local_cert, 'rb') as f:
            b = f.read()
            cert = x509.load_pem_x509_certificate(b, default_backend())
            delta = cert.not_valid_after - datetime.datetime.now()
            logger.info("{}/{}: existing cert expiry: {}".format(fqdn, cert_name, delta))
            if delta.total_seconds() < 3600 * 24 * 60:
                logger.info("{}/{}: expires soon, regenerating".format(fqdn, cert_name))
                generate_cert = True
    else:
        generate_cert = True

    if not generate_cert:
        return False

    local_csr_f = tempfile.NamedTemporaryFile(delete=False)
    local_csr = local_csr_f.name
    local_csr_f.close()

    local_config = openssl_config(san)

    subprocess.check_call([
        'openssl', 'req', '-new',
        '-key', local_key,
        '-out', local_csr,
        '-subj', str(subj),
        '-config', local_config,
        '-reqexts', 'SAN',
    ])

    pki.sign(local_csr, local_cert, local_config, days)

    c.put(local=local_key, remote=remote_key)
    c.put(local=local_cert, remote=remote_cert)

    os.remove(local_csr)
    os.remove(local_config)
    return True


def configure_k8s(username, ca, cert, key):
    subprocess.check_call([
        'kubectl', 'config',
        'set-cluster', cluster,
        '--certificate-authority=' + ca,
        '--embed-certs=true',
        '--server=https://' + cluster + ':4001',
    ])
    subprocess.check_call([
        'kubectl', 'config',
        'set-credentials', username,
        '--client-certificate=' + cert,
        '--client-key=' + key,
        '--embed-certs=true',
    ])
    subprocess.check_call([
        'kubectl', 'config',
        'set-context', cluster,
        '--cluster=' + cluster,
        '--user=' + username,
    ])
    subprocess.check_call([
        'kubectl', 'config',
        'use-context', cluster,
    ])

def admincreds(args):
    if len(args) != 1:
        sys.stderr.write("Usage: admincreds q3k\n")
        return 1
    username = args[0]

    pki = PKI()

    local_key = os.path.join(local_root, '.kubectl/admin.key')
    local_cert = os.path.join(local_root, '.kubectl/admin.crt')
    local_csr = os.path.join(local_root, '.kubectl/admin.csr')

    kubectl = os.path.join(local_root, '.kubectl')
    if not os.path.exists(kubectl):
        os.mkdir(kubectl)

    generate_cert = False
    if not os.path.exists(local_key):
        subprocess.check_call([
            'openssl', 'genrsa', '-out', local_key, '4096',
        ])
        generate_cert = True

    if os.path.exists(local_cert):
        with open(local_cert, 'rb') as f:
            b = f.read()
            cert = x509.load_pem_x509_certificate(b, default_backend())
            delta = cert.not_valid_after - datetime.datetime.now()
            logger.info("admin: existing cert expiry: {}".format(delta))
            if delta.total_seconds() < 3600 * 24:
                logger.info("admin: expires soon, regenerating")
                generate_cert = True
    else:
        generate_cert = True

    if not generate_cert:
        return configure_k8s(username, pki.cacert, local_cert, local_key)

    local_config = openssl_config([])
    subj = Subject('system:masters', "Kubernetes Admin Account for {}".format(username), username)

    subprocess.check_call([
        'openssl', 'req', '-new',
        '-key', local_key,
        '-out', local_csr,
        '-subj', str(subj),
        '-config', local_config,
        '-reqexts', 'SAN',
    ])

    pki.sign(local_csr, local_cert, local_config, 5)
    os.remove(local_config)

    configure_k8s(username, pki.cacert, local_cert, local_key)


def nodestrap(args):
    if len(args) != 1:
        sys.stderr.write("Usage: nodestrap bc01n01.hswaw.net\n")
        return 1
    fqdn = args[0]

    logger.info("Nodestrapping {}...".format(fqdn))

    c = fabric.Connection('root@{}'.format(fqdn))
    p = PKI()

    modified = False
    modified |= remote_cert(p, c, fqdn, "node", Subject(Subject.hswaw, 'Node Certificate', fqdn))
    modified |= remote_cert(p, c, fqdn, "kube-node", Subject('system:nodes', 'Kubelet Certificate', 'system:node:' + fqdn), san=[fqdn,])
    for component in ['controller-manager', 'proxy', 'scheduler']:
        o = 'system:kube-{}'.format(component)
        ou = 'Kuberneter Component {}'.format(component)
        modified |= shared_cert(p, c, fqdn, 'kube-{}'.format(component), Subject(o, ou, o))
    modified |= shared_cert(p, c, fqdn, 'kube-apiserver', Subject(Subject.hswaw, 'Kubernetes API', cluster))
    modified |= shared_cert(p, c, fqdn, 'kube-serviceaccounts', Subject(Subject.hswaw, 'Kubernetes Service Account Signer', 'service-accounts'))

    if modified:
        logger.info('{}: cert(s) modified, restarting services...'.format(fqdn))

        services = [
            'kubelet', 'kube-proxy',
            'kube-apiserver', 'kube-controller-manager', 'kube-scheduler',
            'etcd'
        ]

        for s in services:
            c.run('systemctl stop {}'.format(s))
        for s in services[::-1]:
            c.run('systemctl start {}'.format(s))

def usage():
    sys.stderr.write("Usage: {} <nodestrap|admincreds>\n".format(sys.argv[0]))

def main():
    if len(sys.argv) < 2:
        usage()
        return 1

    mode = sys.argv[1]
    if mode == "nodestrap":
        return nodestrap(sys.argv[2:])
    elif mode == "admincreds":
        return admincreds(sys.argv[2:])
    else:
        usage()
        return 1

if __name__ == '__main__':
    sys.exit(main() or 0)
