diff options
Diffstat (limited to 'daemons/dnssec/ipa-ods-exporter')
-rwxr-xr-x | daemons/dnssec/ipa-ods-exporter | 96 |
1 files changed, 60 insertions, 36 deletions
diff --git a/daemons/dnssec/ipa-ods-exporter b/daemons/dnssec/ipa-ods-exporter index 913b418af..c6de5acbd 100755 --- a/daemons/dnssec/ipa-ods-exporter +++ b/daemons/dnssec/ipa-ods-exporter @@ -9,6 +9,9 @@ This program uses the same socket and protocol as original signerd and should be activated via systemd socket activation using "ods-signer" command line utility. +Alternativelly, it can be called directly and a command can be supplied as +first command line argument. + Purpose of this replacement is to upload keys generated by OpenDNSSEC to LDAP. """ @@ -334,7 +337,7 @@ def hex_set(s): out.add("0x%s" % hexlify(i)) return out -def receive_zone_name(log): +def receive_systemd_command(log): fds = systemd.daemon.listen_fds() if len(fds) != 1: raise KeyError('Exactly one socket is expected.') @@ -345,36 +348,40 @@ def receive_zone_name(log): log.debug('accepted new connection %s', repr(conn)) # this implements cmdhandler_handle_cmd() logic - cmd = conn.recv(ODS_SE_MAXLINE) - cmd = cmd.strip() - - try: - if cmd == 'ipa-hsm-update': - msg = 'HSM synchronization finished, exiting.' - conn.send('%s\n' % msg) - log.info(msg) - sys.exit(0) - - elif not cmd.startswith('update '): - conn.send('Command "%s" is not supported by IPA; ' \ - 'HSM synchronization was finished and the command ' \ - 'will be ignored.\n' % cmd) - log.info('Ignoring unsupported command "%s".', cmd) - sys.exit(0) - - else: - zone_name = cmd2ods_zone_name(cmd) - conn.send('Update request for zone "%s" queued.\n' % zone_name) - log.info('Processing command: "%s"', cmd) - - finally: + cmd = conn.recv(ODS_SE_MAXLINE).strip() + log.debug('received command "%s" from systemd socket', cmd) + return (cmd, conn) + +def parse_command(cmd): + """Parse command to (exit code, message, zone_name) tuple. + + Exit code None means that execution should continue. + """ + if cmd == 'ipa-hsm-update': + return (0, + 'HSM synchronization finished, exiting.', + None) + + elif not cmd.startswith('update '): + return (0, + 'Command "%s" is not supported by IPA; ' + 'HSM synchronization was finished and the command ' + 'will be ignored.\n' % cmd, + None) + + else: + zone_name = cmd2ods_zone_name(cmd) + return (None, + 'Update request for zone "%s" queued.\n' % zone_name, + zone_name) + +def send_systemd_reply(conn, reply): # Reply & close connection early. # This is necessary to let Enforcer to unlock the ODS DB. + conn.send(reply + '\n') conn.shutdown(socket.SHUT_RDWR) conn.close() - return zone_name - def cmd2ods_zone_name(cmd): # ODS stores zone name without trailing period zone_name = cmd[7:].strip() @@ -384,13 +391,17 @@ def cmd2ods_zone_name(cmd): return zone_name log = logging.getLogger('root') -# this service is socket-activated +# this service is usually socket-activated log.addHandler(systemd.journal.JournalHandler()) log.setLevel(level=logging.DEBUG) -if len(sys.argv) != 1: +if len(sys.argv) > 2: print __doc__ sys.exit(1) +# program was likely invoked from console, log to it +elif len(sys.argv) == 2: + console = logging.StreamHandler() + log.addHandler(console) # IPA framework initialization ipalib.api.bootstrap(in_server=True, log=None) # no logging to file @@ -429,16 +440,29 @@ master2ldap_zone_keys_sync(log, ldapkeydb, localhsm) # command receive is delayed so the command will stay in socket queue until # the problem with LDAP server or HSM is fixed try: - zone_name = receive_zone_name(log) - + cmd, conn = receive_systemd_command(log) + if len(sys.argv) != 1: + log.critical('No additional parameters are accepted when ' + 'socket activation is used.') + sys.exit(1) # Handle cases where somebody ran the program without systemd. except KeyError as e: - print 'HSM (key material) sychronization is finished but ' \ - 'this program should be socket-activated by OpenDNSSEC.' - print 'Use "ods-signer" command line utility to synchronize ' \ - 'DNS zone keys and metadata.' - print 'Error: %s' % e - sys.exit(0) + if len(sys.argv) != 2: + print(__doc__) + print('ERROR: Exactly one parameter or socket activation is required.') + sys.exit(1) + conn = None + cmd = sys.argv[1] + +exitcode, msg, zone_name = parse_command(cmd) + +if conn: + send_systemd_reply(conn, msg) +if exitcode is not None: + log.info(msg) + sys.exit(exitcode) +else: + log.debug(msg) ods_keys = get_ods_keys(zone_name) ods_keys_id = set(ods_keys.keys()) |