From 2f4f9a39a6a7293a5de35510c32ab22e36eaa93f Mon Sep 17 00:00:00 2001 From: Jarrod Johnson Date: Thu, 30 Jul 2020 14:44:02 -0400 Subject: [PATCH] Add osdeploy function to trust nodes osdeploy initialize -l will endeavor to do to the local management node the same thing the deployment does to the nodes. --- confluent_server/bin/osdeploy | 42 +++++++++++++++++++++++ confluent_server/confluent/selfservice.py | 41 +++++++++++++--------- 2 files changed, 66 insertions(+), 17 deletions(-) diff --git a/confluent_server/bin/osdeploy b/confluent_server/bin/osdeploy index 94f41b4d..7537d8fb 100644 --- a/confluent_server/bin/osdeploy +++ b/confluent_server/bin/osdeploy @@ -1,7 +1,11 @@ #!/usr/bin/python2 import argparse +import conlfuent.collective as collective import eventlet.green.subprocess as subprocess +import confluent.selfservice as selfservice +import confluent.util as util +import confluent.sshutil as sshutil import glob import os import os.path @@ -39,6 +43,7 @@ def main(args): wiz.add_argument('-t', help='Generate new TLS key for HTTPS operation and register with confluent repository', action='store_true') wiz.add_argument('-p', help='Copy in TFTP contents required for PXE support', action='store_true') wiz.add_argument('-i', help='Interactively prompt for behaviors', action='store_true') + wiz.add_argument('-l', help='Set local management node to have SSH certificates and hosts.equiv/.shosts') osip = sp.add_parser('import', help='Import an OS image from an ISO image') osip.add_argument('imagefile', help='File to use for source of importing') cmdset = ap.parse_args() @@ -48,6 +53,43 @@ def main(args): return initialize(cmdset) ap.print_help() + +def local_node_trust_setup(): + allnodes, domain = selfservice.get_cluster_list() + myname = collective.get_myname() + myprincipals = set([myname]) + neededlines = set([ + 'HostbasedAuthentication yes', 'HostbasedUsesNameFromPacketOnly yes', + 'IgnoreRhosts no']) + if not myname.endswith(domain): + myprincipals.add('{0}.{1}'.format(myname, domain)) + for pubkey in glob.glob('/etc/ssh/ssh_host_*key.pub'): + currpubkey = open(pubkey, 'r').read() + cert = sshutil.sign_host_key(currpubkey, myname, principals) + certfile = currpubkey.replace('key.pub', 'key-cert.pub') + neededlines.add('HostCertificate {0}'.format(certfile)) + if os.path.exists(certfile): + os.unlink(certfile) + with open(certfile) as certout: + certout.write(cert) + with open('/etc/ssh/sshd_config', 'r') as sshconf: + currconfig = sshconf.read().split() + for conline in currconfig: + conline = conline.strip() + neededlines.discard(conline) + if neededlines: + with open('/etc/ssh/sshd_config', 'a') as cfgout: + for currline in neededlines: + cfgout.write(currline) + cfgout.write('\n') + with open('/etc/ssh/shosts.equiv', 'w') as equivout: + for node in util.natural_sort(allnodes): + equivout.write(node + '\n') + with open('/root/.shosts', 'w') as equivout: + for node in util.natural_sort(allnodes): + equivout.write(node + '\n') + + def install_tftp_content(): tftplocation = None candidates = ('/tftpboot', '/var/lib/tftpboot', '/srv/tftpboot', '/srv/tftp') diff --git a/confluent_server/confluent/selfservice.py b/confluent_server/confluent/selfservice.py index 01d38b50..b5a23b19 100644 --- a/confluent_server/confluent/selfservice.py +++ b/confluent_server/confluent/selfservice.py @@ -174,23 +174,7 @@ def handle_request(env, start_response): start_response('200 OK', (('Content-Type', 'text/plain'),)) yield cert elif env['PATH_INFO'] == '/self/nodelist': - nodes = set(cfg.list_nodes()) - domain = None - for node in list(util.natural_sort(nodes)): - if domain is None: - domaininfo = cfg.get_node_attributes(node, 'dns.domain') - domain = domaininfo.get(node, {}).get('dns.domain', {}).get( - 'value', None) - for extraname in get_extra_names(node, cfg): - nodes.add(extraname) - for mgr in configmanager.list_collective(): - nodes.add(mgr) - if domain and domain not in mgr: - nodes.add('{0}.{1}'.format(mgr, domain)) - myname = collective.get_myname() - nodes.add(myname) - if domain and domain not in myname: - nodes.add('{0}.{1}'.format(myname, domain)) + nodes, _ = get_cluster_list(cfg) if isgeneric: start_response('200 OK', (('Content-Type', 'text/plain'),)) for node in util.natural_sort(nodes): @@ -230,3 +214,26 @@ def handle_request(env, start_response): else: start_response('404 Not Found', ()) yield 'Not found' + + +def get_cluster_list(cfg=None): + if cfg is None: + cfg = configmanager.ConfigManager(None) + nodes = set(cfg.list_nodes()) + domain = None + for node in list(util.natural_sort(nodes)): + if domain is None: + domaininfo = cfg.get_node_attributes(node, 'dns.domain') + domain = domaininfo.get(node, {}).get('dns.domain', {}).get( + 'value', None) + for extraname in get_extra_names(node, cfg): + nodes.add(extraname) + for mgr in configmanager.list_collective(): + nodes.add(mgr) + if domain and domain not in mgr: + nodes.add('{0}.{1}'.format(mgr, domain)) + myname = collective.get_myname() + nodes.add(myname) + if domain and domain not in myname: + nodes.add('{0}.{1}'.format(myname, domain)) + return nodes, domain