From dd566ed3c64a69801a9edf3b27f11077aa40ecef Mon Sep 17 00:00:00 2001 From: Matthew Harmsen Date: Mon, 23 Apr 2012 13:39:04 -0700 Subject: PKI Deployment Scriptlets * Completed the following six 'scriptlets': * Dogtag 10: Python 'initialization.py' Installation Scriptlet (https://fedorahosted.org/pki/ticket/147) * Dogtag 10: Python 'instance_layout.py' Installation Scriptlet (https://fedorahosted.org/pki/ticket/75) * Dogtag 10: Python 'webserver_layout.py' Installation Scriptlet (https://fedorahosted.org/pki/ticket/140) * Dogtag 10: Python 'subsystem_layout.py' Installation Scriptlet (https://fedorahosted.org/pki/ticket/141) * Dogtag 10: Python 'war_explosion.py' Installation Scriptlet (https://fedorahosted.org/pki/ticket/76) * Dogtag 10: Python 'finalization.py' Installation Scriptlet (https://fedorahosted.org/pki/ticket/148) * Created numerous PKI deployment helper utilities. * Augmented logging to provide indentation. * Generated logic for installation 'manifest'. * Tested logic using '--dry_run' option and '-p' prefix options. * Per initial review, removed numerous "constants" and consolidated logic into "master" dictionary. * Corrected the following ticket: * Dogtag 10: Fix 'build_dogtag_pki' script to account for 'pki-deploy' RPM (https://fedorahosted.org/pki/ticket/138) Resolves Bugzilla Bug #810047 - build_dogtag_pki fails with requirements for pki-deploy (https://bugzilla.redhat.com/show_bug.cgi?id=810047) * Created the following three 'scriptlets' as 'NOT YET IMPLEMENTED' place-holders: * Dogtag 10: Python 'security_databases.py' Installation Scriptlet (https://fedorahosted.org/pki/ticket/136) * Dogtag 10: Python 'slot_assignment.py' Installation Scriptlet (https://fedorahosted.org/pki/ticket/146) * Dogtag 10: Python 'configuration.py' Configuration Scriptlet (https://fedorahosted.org/pki/ticket/137) --- base/deploy/CMakeLists.txt | 202 ++-- base/deploy/config/pkideployment.cfg | 8 + base/deploy/src/pkidestroy | 106 +- base/deploy/src/pkispawn | 128 ++- base/deploy/src/scriptlets/configuration.py | 52 + base/deploy/src/scriptlets/finalization.py | 109 ++ base/deploy/src/scriptlets/initialization.py | 68 ++ base/deploy/src/scriptlets/instance.py | 105 -- base/deploy/src/scriptlets/instance_layout.py | 97 ++ base/deploy/src/scriptlets/pkiconfig.py | 64 +- base/deploy/src/scriptlets/pkihelper.py | 1195 ++++++++++++++++++---- base/deploy/src/scriptlets/pkilogging.py | 30 +- base/deploy/src/scriptlets/pkimanifest.py | 97 ++ base/deploy/src/scriptlets/pkimessages.py | 132 ++- base/deploy/src/scriptlets/pkiparser.py | 362 +++++++ base/deploy/src/scriptlets/pkiscriptlet.py | 3 +- base/deploy/src/scriptlets/security_databases.py | 54 +- base/deploy/src/scriptlets/slot_assignment.py | 52 + base/deploy/src/scriptlets/subsystem_layout.py | 107 ++ base/deploy/src/scriptlets/war_explosion.py | 69 ++ base/deploy/src/scriptlets/webserver_layout.py | 119 +++ 21 files changed, 2609 insertions(+), 550 deletions(-) create mode 100644 base/deploy/src/scriptlets/configuration.py create mode 100644 base/deploy/src/scriptlets/finalization.py create mode 100644 base/deploy/src/scriptlets/initialization.py delete mode 100644 base/deploy/src/scriptlets/instance.py create mode 100644 base/deploy/src/scriptlets/instance_layout.py create mode 100644 base/deploy/src/scriptlets/pkimanifest.py create mode 100644 base/deploy/src/scriptlets/pkiparser.py create mode 100644 base/deploy/src/scriptlets/slot_assignment.py create mode 100644 base/deploy/src/scriptlets/subsystem_layout.py create mode 100644 base/deploy/src/scriptlets/war_explosion.py create mode 100644 base/deploy/src/scriptlets/webserver_layout.py (limited to 'base') diff --git a/base/deploy/CMakeLists.txt b/base/deploy/CMakeLists.txt index 65c3eacc0..397c9a336 100644 --- a/base/deploy/CMakeLists.txt +++ b/base/deploy/CMakeLists.txt @@ -1,5 +1,26 @@ project(deploy) +set(PKI_SUBSYSTEMS + ca + kra + ocsp + ra + tks + tps +) + +set(TOMCAT_SUBSYSTEMS + ca + kra + ocsp + tks +) + +set(APACHE_SUBSYSTEMS + ra + tps +) + install( FILES src/pkispawn @@ -34,13 +55,22 @@ execute_process( ) install( FILES - src/scriptlets/instance.py + src/scriptlets/configuration.py + src/scriptlets/finalization.py + src/scriptlets/initialization.py + src/scriptlets/instance_layout.py src/scriptlets/pkiconfig.py src/scriptlets/pkihelper.py - src/scriptlets/pkimessages.py src/scriptlets/pkilogging.py + src/scriptlets/pkimanifest.py + src/scriptlets/pkimessages.py + src/scriptlets/pkiparser.py src/scriptlets/pkiscriptlet.py src/scriptlets/security_databases.py + src/scriptlets/slot_assignment.py + src/scriptlets/subsystem_layout.py + src/scriptlets/war_explosion.py + src/scriptlets/webserver_layout.py DESTINATION ${PYTHON_SITE_PACKAGES}/pki/deployment PERMISSIONS @@ -67,60 +97,114 @@ install( #install(CODE "file(MAKE_DIRECTORY \$ENV{DESTDIR}${VAR_INSTALL_DIR}/lock/pki)") #install(CODE "file(MAKE_DIRECTORY \$ENV{DESTDIR}${VAR_INSTALL_DIR}/run/pki)") -# install subsystem directories for pkispawn -install(CODE "file(MAKE_DIRECTORY \$ENV{DESTDIR}${DATA_INSTALL_DIR}/deployment/spawn/ca)") -install(CODE "file(MAKE_DIRECTORY \$ENV{DESTDIR}${DATA_INSTALL_DIR}/deployment/spawn/kra)") -install(CODE "file(MAKE_DIRECTORY \$ENV{DESTDIR}${DATA_INSTALL_DIR}/deployment/spawn/ocsp)") -install(CODE "file(MAKE_DIRECTORY \$ENV{DESTDIR}${DATA_INSTALL_DIR}/deployment/spawn/ra)") -install(CODE "file(MAKE_DIRECTORY \$ENV{DESTDIR}${DATA_INSTALL_DIR}/deployment/spawn/tks)") -install(CODE "file(MAKE_DIRECTORY \$ENV{DESTDIR}${DATA_INSTALL_DIR}/deployment/spawn/tps)") - -# install subsystem directories for pkidestroy -install(CODE "file(MAKE_DIRECTORY \$ENV{DESTDIR}${DATA_INSTALL_DIR}/deployment/destroy/ca)") -install(CODE "file(MAKE_DIRECTORY \$ENV{DESTDIR}${DATA_INSTALL_DIR}/deployment/destroy/kra)") -install(CODE "file(MAKE_DIRECTORY \$ENV{DESTDIR}${DATA_INSTALL_DIR}/deployment/destroy/ocsp)") -install(CODE "file(MAKE_DIRECTORY \$ENV{DESTDIR}${DATA_INSTALL_DIR}/deployment/destroy/ra)") -install(CODE "file(MAKE_DIRECTORY \$ENV{DESTDIR}${DATA_INSTALL_DIR}/deployment/destroy/tks)") -install(CODE "file(MAKE_DIRECTORY \$ENV{DESTDIR}${DATA_INSTALL_DIR}/deployment/destroy/tps)") - -# generate and install symbolic links for pkispawn CA -install( - CODE - "execute_process( - COMMAND - ${CMAKE_COMMAND} -E create_symlink - \"${PYTHON_SITE_PACKAGES}/pki/deployment/instance.py\" - \"\$ENV{DESTDIR}${DATA_INSTALL_DIR}/deployment/spawn/ca/0010_instance\")" -) -install( - CODE - "execute_process( - COMMAND - ${CMAKE_COMMAND} -E create_symlink - \"${PYTHON_SITE_PACKAGES}/pki/deployment/security_databases.py\" - \"\$ENV{DESTDIR}${DATA_INSTALL_DIR}/deployment/spawn/ca/0020_security_databases\")" -) - -# generate and install symbolic links for pkispawn KRA - -# generate and install symbolic links for pkispawn OCSP - -# generate and install symbolic links for pkispawn RA - -# generate and install symbolic links for pkispawn TKS - -# generate and install symbolic links for pkispawn TPS - - -# generate and install symbolic links for pkidestroy CA - -# generate and install symbolic links for pkidestroy KRA - -# generate and install symbolic links for pkidestroy OCSP - -# generate and install symbolic links for pkidestroy RA - -# generate and install symbolic links for pkidestroy TKS - -# generate and install symbolic links for pkidestroy TPS - +# install subsystem directories for pkispawn and pkidestroy +foreach(PKI_SUBSYSTEM ${PKI_SUBSYSTEMS}) + install(CODE "file(MAKE_DIRECTORY \$ENV{DESTDIR}${DATA_INSTALL_DIR}/deployment/spawn/${PKI_SUBSYSTEM})") + install(CODE "file(MAKE_DIRECTORY \$ENV{DESTDIR}${DATA_INSTALL_DIR}/deployment/destroy/${PKI_SUBSYSTEM})") +endforeach(PKI_SUBSYSTEM ${PKI_SUBSYSTEMS}) + +# generate and install shared ordered 'scriptlet' symbolic links +# for CA, KRA, OCSP, and TKS for pkispawn +foreach(TOMCAT_SUBSYSTEM ${TOMCAT_SUBSYSTEMS}) + install(CODE "execute_process(COMMAND + ${CMAKE_COMMAND} -E create_symlink + \"${PYTHON_SITE_PACKAGES}/pki/deployment/initialization.py\" + \"\$ENV{DESTDIR}${DATA_INSTALL_DIR}/deployment/spawn/${TOMCAT_SUBSYSTEM}/000_initialization\")" + ) + install(CODE "execute_process(COMMAND + ${CMAKE_COMMAND} -E create_symlink + \"${PYTHON_SITE_PACKAGES}/pki/deployment/instance_layout.py\" + \"\$ENV{DESTDIR}${DATA_INSTALL_DIR}/deployment/spawn/${TOMCAT_SUBSYSTEM}/010_instance_layout\")" + ) + install(CODE "execute_process(COMMAND + ${CMAKE_COMMAND} -E create_symlink + \"${PYTHON_SITE_PACKAGES}/pki/deployment/webserver_layout.py\" + \"\$ENV{DESTDIR}${DATA_INSTALL_DIR}/deployment/spawn/${TOMCAT_SUBSYSTEM}/020_webserver_layout\")" + ) + install(CODE "execute_process(COMMAND + ${CMAKE_COMMAND} -E create_symlink + \"${PYTHON_SITE_PACKAGES}/pki/deployment/subsystem_layout.py\" + \"\$ENV{DESTDIR}${DATA_INSTALL_DIR}/deployment/spawn/${TOMCAT_SUBSYSTEM}/030_subsystem_layout\")" + ) + install(CODE "execute_process(COMMAND + ${CMAKE_COMMAND} -E create_symlink + \"${PYTHON_SITE_PACKAGES}/pki/deployment/war_explosion.py\" + \"\$ENV{DESTDIR}${DATA_INSTALL_DIR}/deployment/spawn/${TOMCAT_SUBSYSTEM}/040_war_explosion\")" + ) + install(CODE "execute_process(COMMAND + ${CMAKE_COMMAND} -E create_symlink + \"${PYTHON_SITE_PACKAGES}/pki/deployment/security_databases.py\" + \"\$ENV{DESTDIR}${DATA_INSTALL_DIR}/deployment/spawn/${TOMCAT_SUBSYSTEM}/050_security_databases\")" + ) + install(CODE "execute_process(COMMAND + ${CMAKE_COMMAND} -E create_symlink + \"${PYTHON_SITE_PACKAGES}/pki/deployment/slot_assignment.py\" + \"\$ENV{DESTDIR}${DATA_INSTALL_DIR}/deployment/spawn/${TOMCAT_SUBSYSTEM}/060_slot_assignment\")" + ) + install(CODE "execute_process(COMMAND + ${CMAKE_COMMAND} -E create_symlink + \"${PYTHON_SITE_PACKAGES}/pki/deployment/configuration.py\" + \"\$ENV{DESTDIR}${DATA_INSTALL_DIR}/deployment/spawn/${TOMCAT_SUBSYSTEM}/070_configuration\")" + ) + install(CODE "execute_process(COMMAND + ${CMAKE_COMMAND} -E create_symlink + \"${PYTHON_SITE_PACKAGES}/pki/deployment/finalization.py\" + \"\$ENV{DESTDIR}${DATA_INSTALL_DIR}/deployment/spawn/${TOMCAT_SUBSYSTEM}/999_finalization\")" + ) +endforeach(TOMCAT_SUBSYSTEM ${TOMCAT_SUBSYSTEMS}) + +# generate and install shared ordered 'scriptlet' symbolic links +# for RA, and TPS for pkispawn + +# generate and install shared ordered 'scriptlet' symbolic links +# for CA, KRA, OCSP, and TKS for pkidestroy +foreach(TOMCAT_SUBSYSTEM ${TOMCAT_SUBSYSTEMS}) + install(CODE "execute_process(COMMAND + ${CMAKE_COMMAND} -E create_symlink + \"${PYTHON_SITE_PACKAGES}/pki/deployment/initialization.py\" + \"\$ENV{DESTDIR}${DATA_INSTALL_DIR}/deployment/destroy/${TOMCAT_SUBSYSTEM}/000_initialization\")" + ) + install(CODE "execute_process(COMMAND + ${CMAKE_COMMAND} -E create_symlink + \"${PYTHON_SITE_PACKAGES}/pki/deployment/configuration.py\" + \"\$ENV{DESTDIR}${DATA_INSTALL_DIR}/deployment/destroy/${TOMCAT_SUBSYSTEM}/930_configuration\")" + ) +# install(CODE "execute_process(COMMAND +# ${CMAKE_COMMAND} -E create_symlink +# \"${PYTHON_SITE_PACKAGES}/pki/deployment/slot_assignment.py\" +# \"\$ENV{DESTDIR}${DATA_INSTALL_DIR}/deployment/destroy/${TOMCAT_SUBSYSTEM}/940_slot_assignment\")" +# ) + install(CODE "execute_process(COMMAND + ${CMAKE_COMMAND} -E create_symlink + \"${PYTHON_SITE_PACKAGES}/pki/deployment/security_databases.py\" + \"\$ENV{DESTDIR}${DATA_INSTALL_DIR}/deployment/destroy/${TOMCAT_SUBSYSTEM}/950_security_databases\")" + ) + install(CODE "execute_process(COMMAND + ${CMAKE_COMMAND} -E create_symlink + \"${PYTHON_SITE_PACKAGES}/pki/deployment/war_explosion.py\" + \"\$ENV{DESTDIR}${DATA_INSTALL_DIR}/deployment/destroy/${TOMCAT_SUBSYSTEM}/960_war_explosion\")" + ) + install(CODE "execute_process(COMMAND + ${CMAKE_COMMAND} -E create_symlink + \"${PYTHON_SITE_PACKAGES}/pki/deployment/subsystem_layout.py\" + \"\$ENV{DESTDIR}${DATA_INSTALL_DIR}/deployment/destroy/${TOMCAT_SUBSYSTEM}/970_subsystem_layout\")" + ) + install(CODE "execute_process(COMMAND + ${CMAKE_COMMAND} -E create_symlink + \"${PYTHON_SITE_PACKAGES}/pki/deployment/webserver_layout.py\" + \"\$ENV{DESTDIR}${DATA_INSTALL_DIR}/deployment/destroy/${TOMCAT_SUBSYSTEM}/980_webserver_layout\")" + ) + install(CODE "execute_process(COMMAND + ${CMAKE_COMMAND} -E create_symlink + \"${PYTHON_SITE_PACKAGES}/pki/deployment/instance_layout.py\" + \"\$ENV{DESTDIR}${DATA_INSTALL_DIR}/deployment/destroy/${TOMCAT_SUBSYSTEM}/990_instance_layout\")" + ) + install(CODE "execute_process(COMMAND + ${CMAKE_COMMAND} -E create_symlink + \"${PYTHON_SITE_PACKAGES}/pki/deployment/finalization.py\" + \"\$ENV{DESTDIR}${DATA_INSTALL_DIR}/deployment/destroy/${TOMCAT_SUBSYSTEM}/999_finalization\")" + ) +endforeach(TOMCAT_SUBSYSTEM ${TOMCAT_SUBSYSTEMS}) + +# generate and install shared ordered 'scriptlet' symbolic links +# for RA, and TPS for pkidestroy diff --git a/base/deploy/config/pkideployment.cfg b/base/deploy/config/pkideployment.cfg index db9ce54dd..954fa935d 100644 --- a/base/deploy/config/pkideployment.cfg +++ b/base/deploy/config/pkideployment.cfg @@ -1,5 +1,8 @@ [Common] +pki_source_root=/usr/share/pki pki_instance_root=/var/lib/pki +pki_instance_configuration_root=/etc/pki +pki_instance_log_root=/var/log/pki pki_instance_name=instance pki_user=pkiuser pki_group=pkiuser @@ -10,19 +13,24 @@ pki_http_port=80 pki_https_port=443 [Tomcat] pki_web_server=Tomcat +pki_tomcat_root=/usr/share/tomcat pki_http_port=8080 pki_https_port=8443 pki_ajp_port=8009 pki_security_manager=true [CA] pki_subsystem=CA +pki_war_name=ca.war [KRA] pki_subsystem=KRA +pki_war_name=kra.war [OCSP] pki_subsystem=OCSP +pki_war_name=ocsp.war [RA] pki_subsystem=RA [TKS] pki_subsystem=TKS +pki_war_name=tks.war [TPS] pki_subsystem=TPS diff --git a/base/deploy/src/pkidestroy b/base/deploy/src/pkidestroy index a762e143a..6d0afd2b0 100755 --- a/base/deploy/src/pkidestroy +++ b/base/deploy/src/pkidestroy @@ -23,15 +23,16 @@ import sys if not hasattr(sys, "hexversion") or sys.hexversion < 0x020700f0: print "Python version %s.%s.%s is too old." % sys.version_info[:3] - print "Please upgrade to at least Python 2.7.0." + print "Please upgrade to at least Python 2.7.0." sys.exit(1) try: import argparse import logging import os import pprint + from time import strftime as date from pki.deployment import pkiconfig as config - from pki.deployment import pkihelper + from pki.deployment import pkiparser as parse from pki.deployment import pkilogging from pki.deployment import pkimessages as log except ImportError: @@ -52,23 +53,34 @@ def main(argv): if not os.geteuid() == 0: sys.exit("'%s' must be run as root!" % argv[0]) + # Set the umask + os.umask(config.PKI_DEPLOYMENT_DEFAULT_UMASK) + + # Generate a timestamp + config.pki_timestamp = date('%Y%m%d%H%M%S') + # Initialize 'pretty print' for objects pp = pprint.PrettyPrinter(indent=4) # Read and process command-line arguments. - pkihelper.process_command_line_arguments(argv) + parse.process_command_line_arguments(argv) # Enable 'pkidestroy' logging. - config.pki_log_dir = config.pki_root_prefix +\ - config.PKIDESTROY_LOG_PATH - config.pki_log_name = config.PKIDESTROY_LOG_PREFIX +\ - config.pki_subsystem.lower() +\ - config.PKIDESTROY_LOG_SUFFIX + if not config.pki_dry_run_flag: + config.pki_log_dir = config.pki_root_prefix +\ + "/var/log" + config.pki_log_name = "pki" + "-" +\ + config.pki_subsystem.lower() +\ + "-" + "destroy" + "." +\ + config.pki_timestamp + "." + "log" + else: + config.pki_log_dir = "/dev" + config.pki_log_name = "null" rv = pkilogging.enable_pki_logger(config.pki_log_dir, config.pki_log_name, config.pki_log_level, config.pki_console_log_level, - config.PKIDESTROY_LOGGER) + "pkidestroy") if rv != OSError: config.pki_log = rv else: @@ -76,17 +88,24 @@ def main(argv): sys.exit(1) # Read the specified PKI configuration file. - rv = pkihelper.read_pki_configuration_file() + rv = parse.read_pki_configuration_file() if rv != 0: - config.pki_log.error(PKI_UNABLE_TO_PARSE_1, rv) + config.pki_log.error(PKI_UNABLE_TO_PARSE_1, rv, + extra=config.PKI_INDENTATION_LEVEL_0) sys.exit(1) else: - config.pki_log.debug(log.PKI_DICTIONARY_COMMON) - config.pki_log.debug(pp.pformat(config.pki_common_dict)) - config.pki_log.debug(log.PKI_DICTIONARY_WEB_SERVER) - config.pki_log.debug(pp.pformat(config.pki_web_server_dict)) - config.pki_log.debug(log.PKI_DICTIONARY_SUBSYSTEM) - config.pki_log.debug(pp.pformat(config.pki_subsystem_dict)) + config.pki_log.debug(log.PKI_DICTIONARY_COMMON, + extra=config.PKI_INDENTATION_LEVEL_0) + config.pki_log.debug(pp.pformat(config.pki_common_dict), + extra=config.PKI_INDENTATION_LEVEL_0) + config.pki_log.debug(log.PKI_DICTIONARY_WEB_SERVER, + extra=config.PKI_INDENTATION_LEVEL_0) + config.pki_log.debug(pp.pformat(config.pki_web_server_dict), + extra=config.PKI_INDENTATION_LEVEL_0) + config.pki_log.debug(log.PKI_DICTIONARY_SUBSYSTEM, + extra=config.PKI_INDENTATION_LEVEL_0) + config.pki_log.debug(pp.pformat(config.pki_subsystem_dict), + extra=config.PKI_INDENTATION_LEVEL_0) # Override PKI configuration file values with 'custom' command-line values. if not config.pki_instance_name is None: @@ -101,51 +120,56 @@ def main(argv): if not config.pki_ajp_port is None: config.pki_web_server_dict['pki_ajp_port'] =\ config.pki_ajp_port - config.pki_log.debug(log.PKI_DICTIONARY_COMMON) - config.pki_log.debug(pp.pformat(config.pki_common_dict)) - config.pki_log.debug(log.PKI_DICTIONARY_WEB_SERVER) - config.pki_log.debug(pp.pformat(config.pki_web_server_dict)) - config.pki_log.debug(log.PKI_DICTIONARY_SUBSYSTEM) - config.pki_log.debug(pp.pformat(config.pki_subsystem_dict)) + config.pki_log.debug(log.PKI_DICTIONARY_COMMON, + extra=config.PKI_INDENTATION_LEVEL_0) + config.pki_log.debug(pp.pformat(config.pki_common_dict), + extra=config.PKI_INDENTATION_LEVEL_0) + config.pki_log.debug(log.PKI_DICTIONARY_WEB_SERVER, + extra=config.PKI_INDENTATION_LEVEL_0) + config.pki_log.debug(pp.pformat(config.pki_web_server_dict), + extra=config.PKI_INDENTATION_LEVEL_0) + config.pki_log.debug(log.PKI_DICTIONARY_SUBSYSTEM, + extra=config.PKI_INDENTATION_LEVEL_0) + config.pki_log.debug(pp.pformat(config.pki_subsystem_dict), + extra=config.PKI_INDENTATION_LEVEL_0) # Combine the various sectional dictionaries into a PKI master dictionary - pkihelper.create_pki_master_dictionary() - config.pki_log.debug(log.PKI_DICTIONARY_MASTER) - config.pki_log.debug(pp.pformat(config.pki_master_dict)) + parse.compose_pki_master_dictionary() + config.pki_master_dict['pki_destroy_log'] = config.pki_log_dir + "/" +\ + config.pki_log_name + config.pki_log.debug(log.PKI_DICTIONARY_MASTER, + extra=config.PKI_INDENTATION_LEVEL_0) + config.pki_log.debug(pp.pformat(config.pki_master_dict), + extra=config.PKI_INDENTATION_LEVEL_0) # Remove the specified PKI subsystem. - pki_scriptlets_path = config.pki_root_prefix +\ - config.PKIDESTROY_PATH +\ + pki_scriptlets_path = "/usr/share/pki/deployment/destroy" +\ "/" + config.pki_subsystem.lower() if not os.path.exists(pki_scriptlets_path) or\ not os.path.isdir(pki_scriptlets_path): config.pki_log.error(log.PKI_DIRECTORY_MISSING_OR_NOT_A_DIRECTORY_1, - pki_scriptlets_path) + pki_scriptlets_path, + extra=config.PKI_INDENTATION_LEVEL_0) sys.exit(1) pki_subsystem_scriptlets = os.listdir(pki_scriptlets_path) pki_subsystem_scriptlets.sort() # Process the various "scriptlets" for the specified PKI subsystem. rv = 0 - config.pki_log.info(log.PKIDESTROY_BEGIN_MESSAGE_2, - config.pki_subsystem, - config.pki_master_dict['pki_instance_name']) for pki_scriptlet in pki_subsystem_scriptlets: - scriptlet = __import__(config.PKI_DEPLOYMENT_SCRIPTLETS_MODULE +\ - '.' + pki_scriptlet[5:], - fromlist = [pki_scriptlet[5:]]) + scriptlet = __import__("pki.deployment" +\ + "." + pki_scriptlet[4:], + fromlist = [pki_scriptlet[4:]]) instance = scriptlet.PkiScriptlet() rv = instance.destroy() if rv != 0: sys.exit(1) - config.pki_log.info(log.PKIDESTROY_END_MESSAGE_2, - config.pki_subsystem, - config.pki_master_dict['pki_instance_name']) - config.pki_log.debug(log.PKI_DICTIONARY_MASTER) - config.pki_log.debug(pp.pformat(config.pki_master_dict)) + config.pki_log.debug(log.PKI_DICTIONARY_MASTER, + extra=config.PKI_INDENTATION_LEVEL_0) + config.pki_log.debug(pp.pformat(config.pki_master_dict), + extra=config.PKI_INDENTATION_LEVEL_0) # PKI Deployment Entry Point if __name__ == "__main__": main(sys.argv) - diff --git a/base/deploy/src/pkispawn b/base/deploy/src/pkispawn index a48a4753c..2ac21a60a 100755 --- a/base/deploy/src/pkispawn +++ b/base/deploy/src/pkispawn @@ -23,15 +23,16 @@ import sys if not hasattr(sys, "hexversion") or sys.hexversion < 0x020700f0: print "Python version %s.%s.%s is too old." % sys.version_info[:3] - print "Please upgrade to at least Python 2.7.0." + print "Please upgrade to at least Python 2.7.0." sys.exit(1) try: import argparse import logging import os import pprint + from time import strftime as date from pki.deployment import pkiconfig as config - from pki.deployment import pkihelper + from pki.deployment import pkiparser as parse from pki.deployment import pkilogging from pki.deployment import pkimessages as log except ImportError: @@ -55,40 +56,49 @@ def main(argv): # Set the umask os.umask(config.PKI_DEPLOYMENT_DEFAULT_UMASK) + # Generate a timestamp + config.pki_timestamp = date('%Y%m%d%H%M%S') + # Initialize 'pretty print' for objects pp = pprint.PrettyPrinter(indent=4) # Read and process command-line arguments. - pkihelper.process_command_line_arguments(argv) + parse.process_command_line_arguments(argv) # Enable 'pkispawn' logging. rv = 0 if not config.pki_update_flag: - pki_deployment_begin = log.PKISPAWN_BEGIN_MESSAGE_2 - pki_deployment_end = log.PKISPAWN_END_MESSAGE_2 - config.pki_log_dir = config.pki_root_prefix +\ - config.PKISPAWN_LOG_PATH - config.pki_log_name = config.PKISPAWN_LOG_PREFIX +\ - config.pki_subsystem.lower() +\ - config.PKISPAWN_LOG_SUFFIX + if not config.pki_dry_run_flag: + config.pki_log_dir = config.pki_root_prefix +\ + "/var/log" + config.pki_log_name = "pki" + "-" +\ + config.pki_subsystem.lower() +\ + "-" + "spawn" + "." +\ + config.pki_timestamp + "." + "log" + else: + config.pki_log_dir = "/dev" + config.pki_log_name = "null" rv = pkilogging.enable_pki_logger(config.pki_log_dir, config.pki_log_name, config.pki_log_level, config.pki_console_log_level, - config.PKISPAWN_LOGGER) + "pkispawn") else: - pki_deployment_begin = log.PKIRESPAWN_BEGIN_MESSAGE_2 - pki_deployment_end = log.PKIRESPAWN_END_MESSAGE_2 - config.pki_log_dir = config.pki_root_prefix +\ - config.PKIRESPAWN_LOG_PATH - config.pki_log_name = config.PKIRESPAWN_LOG_PREFIX +\ - config.pki_subsystem.lower() +\ - config.PKIRESPAWN_LOG_SUFFIX + if not config.pki_dry_run_flag: + config.pki_log_dir = config.pki_root_prefix +\ + "/var/log" + config.pki_log_name = "pki" + "-" +\ + config.pki_subsystem.lower() +\ + "-" + "respawn" + "." +\ + config.pki_timestamp + "." + "log" + else: + config.pki_log_dir = "/dev" + config.pki_log_name = "null" rv = pkilogging.enable_pki_logger(config.pki_log_dir, config.pki_log_name, config.pki_log_level, config.pki_console_log_level, - config.PKIRESPAWN_LOGGER) + "pkirespawn") if rv != OSError: config.pki_log = rv else: @@ -96,17 +106,24 @@ def main(argv): sys.exit(1) # Read the specified PKI configuration file. - rv = pkihelper.read_pki_configuration_file() + rv = parse.read_pki_configuration_file() if rv != 0: - config.pki_log.error(PKI_UNABLE_TO_PARSE_1, rv) + config.pki_log.error(PKI_UNABLE_TO_PARSE_1, rv, + extra=config.PKI_INDENTATION_LEVEL_0) sys.exit(1) else: - config.pki_log.debug(log.PKI_DICTIONARY_COMMON) - config.pki_log.debug(pp.pformat(config.pki_common_dict)) - config.pki_log.debug(log.PKI_DICTIONARY_WEB_SERVER) - config.pki_log.debug(pp.pformat(config.pki_web_server_dict)) - config.pki_log.debug(log.PKI_DICTIONARY_SUBSYSTEM) - config.pki_log.debug(pp.pformat(config.pki_subsystem_dict)) + config.pki_log.debug(log.PKI_DICTIONARY_COMMON, + extra=config.PKI_INDENTATION_LEVEL_0) + config.pki_log.debug(pp.pformat(config.pki_common_dict), + extra=config.PKI_INDENTATION_LEVEL_0) + config.pki_log.debug(log.PKI_DICTIONARY_WEB_SERVER, + extra=config.PKI_INDENTATION_LEVEL_0) + config.pki_log.debug(pp.pformat(config.pki_web_server_dict), + extra=config.PKI_INDENTATION_LEVEL_0) + config.pki_log.debug(log.PKI_DICTIONARY_SUBSYSTEM, + extra=config.PKI_INDENTATION_LEVEL_0) + config.pki_log.debug(pp.pformat(config.pki_subsystem_dict), + extra=config.PKI_INDENTATION_LEVEL_0) # Override PKI configuration file values with 'custom' command-line values. if not config.pki_instance_name is None: @@ -121,39 +138,50 @@ def main(argv): if not config.pki_ajp_port is None: config.pki_web_server_dict['pki_ajp_port'] =\ config.pki_ajp_port - config.pki_log.debug(log.PKI_DICTIONARY_COMMON) - config.pki_log.debug(pp.pformat(config.pki_common_dict)) - config.pki_log.debug(log.PKI_DICTIONARY_WEB_SERVER) - config.pki_log.debug(pp.pformat(config.pki_web_server_dict)) - config.pki_log.debug(log.PKI_DICTIONARY_SUBSYSTEM) - config.pki_log.debug(pp.pformat(config.pki_subsystem_dict)) + config.pki_log.debug(log.PKI_DICTIONARY_COMMON, + extra=config.PKI_INDENTATION_LEVEL_0) + config.pki_log.debug(pp.pformat(config.pki_common_dict), + extra=config.PKI_INDENTATION_LEVEL_0) + config.pki_log.debug(log.PKI_DICTIONARY_WEB_SERVER, + extra=config.PKI_INDENTATION_LEVEL_0) + config.pki_log.debug(pp.pformat(config.pki_web_server_dict), + extra=config.PKI_INDENTATION_LEVEL_0) + config.pki_log.debug(log.PKI_DICTIONARY_SUBSYSTEM, + extra=config.PKI_INDENTATION_LEVEL_0) + config.pki_log.debug(pp.pformat(config.pki_subsystem_dict), + extra=config.PKI_INDENTATION_LEVEL_0) # Combine the various sectional dictionaries into a PKI master dictionary - pkihelper.create_pki_master_dictionary() - config.pki_log.debug(log.PKI_DICTIONARY_MASTER) - config.pki_log.debug(pp.pformat(config.pki_master_dict)) + parse.compose_pki_master_dictionary() + if not config.pki_update_flag: + config.pki_master_dict['pki_spawn_log'] = config.pki_log_dir + "/" +\ + config.pki_log_name + else: + config.pki_master_dict['pki_respawn_log'] = config.pki_log_dir + "/" +\ + config.pki_log_name + config.pki_log.debug(log.PKI_DICTIONARY_MASTER, + extra=config.PKI_INDENTATION_LEVEL_0) + config.pki_log.debug(pp.pformat(config.pki_master_dict), + extra=config.PKI_INDENTATION_LEVEL_0) # Install and configure the specified PKI subsystem. - pki_scriptlets_path = config.pki_root_prefix +\ - config.PKISPAWN_PATH +\ + pki_scriptlets_path = "/usr/share/pki/deployment/spawn" +\ "/" + config.pki_subsystem.lower() if not os.path.exists(pki_scriptlets_path) or\ not os.path.isdir(pki_scriptlets_path): config.pki_log.error(log.PKI_DIRECTORY_MISSING_OR_NOT_A_DIRECTORY_1, - pki_scriptlets_path) + pki_scriptlets_path, + extra=config.PKI_INDENTATION_LEVEL_0) sys.exit(1) pki_subsystem_scriptlets = os.listdir(pki_scriptlets_path) pki_subsystem_scriptlets.sort() # Process the various "scriptlets" for the specified PKI subsystem. rv = 0 - config.pki_log.info(pki_deployment_begin, - config.pki_subsystem, - config.pki_master_dict['pki_instance_name']) for pki_scriptlet in pki_subsystem_scriptlets: - scriptlet = __import__(config.PKI_DEPLOYMENT_SCRIPTLETS_MODULE +\ - '.' + pki_scriptlet[5:], - fromlist = [pki_scriptlet[5:]]) + scriptlet = __import__("pki.deployment" +\ + "." + pki_scriptlet[4:], + fromlist = [pki_scriptlet[4:]]) instance = scriptlet.PkiScriptlet() if not config.pki_update_flag: rv = instance.spawn() @@ -161,14 +189,12 @@ def main(argv): rv = instance.respawn() if rv != 0: sys.exit(1) - config.pki_log.info(pki_deployment_end, - config.pki_subsystem, - config.pki_master_dict['pki_instance_name']) - config.pki_log.debug(log.PKI_DICTIONARY_MASTER) - config.pki_log.debug(pp.pformat(config.pki_master_dict)) + config.pki_log.debug(log.PKI_DICTIONARY_MASTER, + extra=config.PKI_INDENTATION_LEVEL_0) + config.pki_log.debug(pp.pformat(config.pki_master_dict), + extra=config.PKI_INDENTATION_LEVEL_0) # PKI Deployment Entry Point if __name__ == "__main__": main(sys.argv) - diff --git a/base/deploy/src/scriptlets/configuration.py b/base/deploy/src/scriptlets/configuration.py new file mode 100644 index 000000000..45b325ce7 --- /dev/null +++ b/base/deploy/src/scriptlets/configuration.py @@ -0,0 +1,52 @@ +#!/usr/bin/python -t +# Authors: +# Matthew Harmsen +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; version 2 of the License. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Copyright (C) 2012 Red Hat, Inc. +# All rights reserved. +# + +# PKI Deployment Imports +import pkiconfig as config +from pkiconfig import pki_master_dict as master +import pkimessages as log +import pkiscriptlet + + +# PKI Deployment Instance Population Classes +class PkiScriptlet(pkiscriptlet.AbstractBasePkiScriptlet): + rv = 0 + + def spawn(self): + config.pki_log.info(log.CONFIGURATION_SPAWN_1, __name__, + extra=config.PKI_INDENTATION_LEVEL_1) + config.pki_log.info("NOT YET IMPLEMENTED", + extra=config.PKI_INDENTATION_LEVEL_2) + return self.rv + + def respawn(self): + config.pki_log.info(log.CONFIGURATION_RESPAWN_1, __name__, + extra=config.PKI_INDENTATION_LEVEL_1) + config.pki_log.info("NOT YET IMPLEMENTED", + extra=config.PKI_INDENTATION_LEVEL_2) + return self.rv + + def destroy(self): + config.pki_log.info(log.CONFIGURATION_DESTROY_1, __name__, + extra=config.PKI_INDENTATION_LEVEL_1) + config.pki_log.info("NOT YET IMPLEMENTED", + extra=config.PKI_INDENTATION_LEVEL_2) + return self.rv diff --git a/base/deploy/src/scriptlets/finalization.py b/base/deploy/src/scriptlets/finalization.py new file mode 100644 index 000000000..60073262d --- /dev/null +++ b/base/deploy/src/scriptlets/finalization.py @@ -0,0 +1,109 @@ +#!/usr/bin/python -t +# Authors: +# Matthew Harmsen +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; version 2 of the License. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Copyright (C) 2012 Red Hat, Inc. +# All rights reserved. +# + +# PKI Deployment Imports +import pkiconfig as config +from pkiconfig import pki_master_dict as master +import pkihelper as util +import pkimanifest as manifest +import pkimessages as log +import pkiscriptlet + + +# PKI Deployment Instance Population Classes +class PkiScriptlet(pkiscriptlet.AbstractBasePkiScriptlet): + rv = 0 + + def spawn(self): + config.pki_log.info(log.FINALIZATION_SPAWN_1, __name__, + extra=config.PKI_INDENTATION_LEVEL_1) + # Save a copy of the configuration file used by this process + # (which may be used later by 'pkidestroy') + util.file.copy(config.pkideployment_cfg, + master['pki_subsystem_registry_path'] +\ + "/" + config.PKI_DEPLOYMENT_DEFAULT_CONFIGURATION_FILE) + # Save a timestamped copy of the installation manifest file + filename = master['pki_root_prefix'] +\ + config.PKI_DEPLOYMENT_REGISTRY_ROOT + "/" +\ + master['pki_instance_name'] + "/" +\ + master['pki_subsystem'].lower() +"/" +\ + "spawn" + "_" + "manifest" + "." +\ + master['pki_timestamp'] + "." + "csv" + config.pki_log.info(log.PKI_MANIFEST_MESSAGE_1, filename, + extra=config.PKI_INDENTATION_LEVEL_2) + # for record in manifest.database: + # print tuple(record) + if not config.pki_dry_run_flag: + manifest.file.register(filename) + manifest.file.write() + util.file.modify(filename, silent=True) + # Log final process messages + config.pki_log.info(log.PKISPAWN_END_MESSAGE_2, + master['pki_subsystem'], + master['pki_instance_name'], + extra=config.PKI_INDENTATION_LEVEL_0) + if not config.pki_dry_run_flag: + util.file.modify(master['pki_spawn_log'], silent=True) + return self.rv + + def respawn(self): + config.pki_log.info(log.FINALIZATION_RESPAWN_1, __name__, + extra=config.PKI_INDENTATION_LEVEL_1) + # Save a copy of the configuration file used by this process + # (which may be used later by 'pkidestroy') + util.file.copy(config.pkideployment_cfg, + master['pki_subsystem_registry_path'] +\ + "/" + config.PKI_DEPLOYMENT_DEFAULT_CONFIGURATION_FILE, + overwrite_flag=True) + # Save a timestamped copy of the updated manifest file + filename = master['pki_root_prefix'] +\ + config.PKI_DEPLOYMENT_REGISTRY_ROOT + "/" +\ + master['pki_instance_name'] + "/" +\ + master['pki_subsystem'].lower() +"/" +\ + "respawn" + "_" + "manifest" + "." +\ + master['pki_timestamp'] + "." + "csv" + config.pki_log.info(log.PKI_MANIFEST_MESSAGE_1, filename, + extra=config.PKI_INDENTATION_LEVEL_2) + # for record in manifest.database: + # print tuple(record) + if not config.pki_dry_run_flag: + manifest.file.register(filename) + manifest.file.write() + util.file.modify(filename, silent=True) + # Log final process messages + config.pki_log.info(log.PKIRESPAWN_END_MESSAGE_2, + master['pki_subsystem'], + master['pki_instance_name'], + extra=config.PKI_INDENTATION_LEVEL_0) + if not config.pki_dry_run_flag: + util.file.modify(master['pki_respawn_log'], silent=True) + return self.rv + + def destroy(self): + config.pki_log.info(log.FINALIZATION_DESTROY_1, __name__, + extra=config.PKI_INDENTATION_LEVEL_1) + config.pki_log.info(log.PKIDESTROY_END_MESSAGE_2, + master['pki_subsystem'], + master['pki_instance_name'], + extra=config.PKI_INDENTATION_LEVEL_0) + if not config.pki_dry_run_flag: + util.file.modify(master['pki_destroy_log'], silent=True) + return self.rv diff --git a/base/deploy/src/scriptlets/initialization.py b/base/deploy/src/scriptlets/initialization.py new file mode 100644 index 000000000..67c93254d --- /dev/null +++ b/base/deploy/src/scriptlets/initialization.py @@ -0,0 +1,68 @@ +#!/usr/bin/python -t +# Authors: +# Matthew Harmsen +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; version 2 of the License. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Copyright (C) 2012 Red Hat, Inc. +# All rights reserved. +# + +# PKI Deployment Imports +import pkiconfig as config +from pkiconfig import pki_master_dict as master +import pkihelper as util +import pkimessages as log +import pkiscriptlet + + +# PKI Deployment Instance Population Classes +class PkiScriptlet(pkiscriptlet.AbstractBasePkiScriptlet): + rv = 0 + + def spawn(self): + config.pki_log.info(log.PKISPAWN_BEGIN_MESSAGE_2, + master['pki_subsystem'], + master['pki_instance_name'], + extra=config.PKI_INDENTATION_LEVEL_0) + config.pki_log.info(log.INITIALIZATION_SPAWN_1, __name__, + extra=config.PKI_INDENTATION_LEVEL_1) + # establish 'uid' and 'gid' + util.identity.set_uid(master['pki_user']) + util.identity.set_gid(master['pki_group']) + return self.rv + + def respawn(self): + config.pki_log.info(log.PKIRESPAWN_BEGIN_MESSAGE_2, + master['pki_subsystem'], + master['pki_instance_name'], + extra=config.PKI_INDENTATION_LEVEL_0) + config.pki_log.info(log.INITIALIZATION_RESPAWN_1, __name__, + extra=config.PKI_INDENTATION_LEVEL_1) + # establish 'uid' and 'gid' + util.identity.set_uid(master['pki_user']) + util.identity.set_gid(master['pki_group']) + return self.rv + + def destroy(self): + config.pki_log.info(log.PKIDESTROY_BEGIN_MESSAGE_2, + master['pki_subsystem'], + master['pki_instance_name'], + extra=config.PKI_INDENTATION_LEVEL_0) + config.pki_log.info(log.INITIALIZATION_DESTROY_1, __name__, + extra=config.PKI_INDENTATION_LEVEL_1) + # establish 'uid' and 'gid' + util.identity.set_uid(master['pki_user']) + util.identity.set_gid(master['pki_group']) + return self.rv diff --git a/base/deploy/src/scriptlets/instance.py b/base/deploy/src/scriptlets/instance.py deleted file mode 100644 index a7ca35c69..000000000 --- a/base/deploy/src/scriptlets/instance.py +++ /dev/null @@ -1,105 +0,0 @@ -#!/usr/bin/python -t -# Authors: -# Matthew Harmsen -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; version 2 of the License. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License along -# with this program; if not, write to the Free Software Foundation, Inc., -# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Copyright (C) 2011 Red Hat, Inc. -# All rights reserved. -# - -# System Imports -import os -import grp -import pwd - -# PKI Deployment Imports -import pkiconfig as config -import pkimessages as log -import pkiscriptlet - - -# PKI Deployment Instance Population Classes -class PkiScriptlet(pkiscriptlet.AbstractBasePkiScriptlet): - rv = 0 - pki_path = config.pki_root_prefix +\ - config.pki_master_dict['pki_instance_root'] - pki_instance_path = pki_path + "/" +\ - config.pki_master_dict['pki_instance_name'] - pki_subsystem_path = pki_instance_path + "/" +\ - config.pki_master_dict['pki_subsystem'].lower() - - def spawn(self): - if not os.path.exists(self.pki_subsystem_path): - config.pki_log.info(log.INSTANCE_SPAWN_1, __name__) - config.pki_log.info(log.INSTANCE_SPAWN_MKDIR_1, - self.pki_subsystem_path) - if not config.pki_dry_run_flag: - try: - pki_gid = grp.getgrnam( - config.pki_master_dict['pki_group'])[2] - pki_uid = pwd.getpwnam( - config.pki_master_dict['pki_user'])[2] - os.mkdir(self.pki_path, - config.PKI_DEPLOYMENT_DEFAULT_DIR_PERMISSIONS) - os.chown(self.pki_path, - pki_uid, - pki_gid) - os.mkdir(self.pki_instance_path, - config.PKI_DEPLOYMENT_DEFAULT_DIR_PERMISSIONS) - os.chown(self.pki_instance_path, - pki_uid, - pki_gid) - os.mkdir(self.pki_subsystem_path, - config.PKI_DEPLOYMENT_DEFAULT_DIR_PERMISSIONS) - os.chown(self.pki_subsystem_path, - pki_uid, - pki_gid) - except KeyError: - self.rv = KeyError - except OSError: - self.rv = OSError - elif not os.path.isdir(self.pki_subsystem_path): - config.pki_log.error( - log.PKI_DIRECTORY_ALREADY_EXISTS_NOT_A_DIRECTORY_1, - self.pki_subsystem_path) - self.rv = -1 - else: - config.pki_log.error(log.PKI_DIRECTORY_ALREADY_EXISTS_1, - self.pki_subsystem_path) - self.rv = -1 - return self.rv - - def respawn(self): - if not os.path.exists(self.pki_subsystem_path) or\ - not os.path.isdir(self.pki_subsystem_path): - config.pki_log.error( - log.PKI_DIRECTORY_MISSING_OR_NOT_A_DIRECTORY_1, - self.pki_subsystem_path) - self.rv = -1 - else: - config.pki_log.info(log.INSTANCE_RESPAWN_1, __name__) - return self.rv - - def destroy(self): - if not os.path.exists(self.pki_subsystem_path) or\ - not os.path.isdir(self.pki_subsystem_path): - config.pki_log.error( - log.PKI_DIRECTORY_MISSING_OR_NOT_A_DIRECTORY_1, - self.pki_subsystem_path) - self.rv = -1 - else: - config.pki_log.info(log.INSTANCE_DESTROY_1, __name__) - return self.rv - diff --git a/base/deploy/src/scriptlets/instance_layout.py b/base/deploy/src/scriptlets/instance_layout.py new file mode 100644 index 000000000..38234f4cc --- /dev/null +++ b/base/deploy/src/scriptlets/instance_layout.py @@ -0,0 +1,97 @@ +#!/usr/bin/python -t +# Authors: +# Matthew Harmsen +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; version 2 of the License. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Copyright (C) 2012 Red Hat, Inc. +# All rights reserved. +# + +# PKI Deployment Imports +import pkiconfig as config +from pkiconfig import pki_master_dict as master +import pkihelper as util +import pkimessages as log +import pkiscriptlet + + +# PKI Deployment Instance Population Classes +class PkiScriptlet(pkiscriptlet.AbstractBasePkiScriptlet): + rv = 0 + + def spawn(self): + config.pki_log.info(log.INSTANCE_SPAWN_1, __name__, + extra=config.PKI_INDENTATION_LEVEL_1) + # establish instance base + util.directory.create(master['pki_path']) + util.directory.create(master['pki_instance_path']) + # establish instance logs + util.directory.create(master['pki_log_path']) + util.directory.create(master['pki_instance_log_path']) + # establish instance configuration + if master['pki_configuration_path'] !=\ + config.PKI_SHARED_CONFIGURATION_ROOT: + util.directory.create(master['pki_configuration_path']) + util.directory.create(master['pki_instance_configuration_path']) + # establish instance registry + util.directory.create(master['pki_registry_path']) + util.directory.create(master['pki_instance_registry_path']) + return self.rv + + def respawn(self): + config.pki_log.info(log.INSTANCE_RESPAWN_1, __name__, + extra=config.PKI_INDENTATION_LEVEL_1) + # update instance base + util.directory.modify(master['pki_path']) + util.directory.modify(master['pki_instance_path']) + # update instance logs + util.directory.modify(master['pki_log_path']) + util.directory.modify(master['pki_instance_log_path']) + # update instance configuration + if master['pki_configuration_path'] !=\ + config.PKI_SHARED_CONFIGURATION_ROOT: + util.directory.modify(master['pki_configuration_path']) + util.directory.modify(master['pki_instance_configuration_path']) + # update instance registry + util.directory.modify(master['pki_registry_path']) + util.directory.modify(master['pki_instance_registry_path']) + return self.rv + + def destroy(self): + config.pki_log.info(log.INSTANCE_DESTROY_1, __name__, + extra=config.PKI_INDENTATION_LEVEL_1) + # remove instance base + if util.directory.is_empty(master['pki_instance_path']): + util.directory.delete(master['pki_instance_path']) + if util.directory.is_empty(master['pki_path']): + util.directory.delete(master['pki_path']) + # remove instance logs + if util.directory.is_empty(master['pki_instance_log_path']): + util.directory.delete(master['pki_instance_log_path']) + if util.directory.is_empty(master['pki_log_path']): + util.directory.delete(master['pki_log_path']) + # remove instance configuration + if util.directory.is_empty(master['pki_instance_configuration_path']): + util.directory.delete(master['pki_instance_configuration_path']) + if util.directory.is_empty(master['pki_configuration_path']) and\ + master['pki_configuration_path'] !=\ + config.PKI_SHARED_CONFIGURATION_ROOT: + util.directory.delete(master['pki_configuration_path']) + # remove instance registry + if util.directory.is_empty(master['pki_instance_registry_path']): + util.directory.delete(master['pki_instance_registry_path']) + if util.directory.is_empty(master['pki_registry_path']): + util.directory.delete(master['pki_registry_path']) + return self.rv diff --git a/base/deploy/src/scriptlets/pkiconfig.py b/base/deploy/src/scriptlets/pkiconfig.py index 7d676c00d..505bfc039 100644 --- a/base/deploy/src/scriptlets/pkiconfig.py +++ b/base/deploy/src/scriptlets/pkiconfig.py @@ -15,7 +15,7 @@ # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -# Copyright (C) 2011 Red Hat, Inc. +# Copyright (C) 2012 Red Hat, Inc. # All rights reserved. # @@ -24,51 +24,50 @@ import logging # PKI Deployment Constants -PKI_DEPLOYMENT_PATH = "/usr/share/pki/deployment" -PKI_DEPLOYMENT_CONFIG_PATH = PKI_DEPLOYMENT_PATH + "/" + "config" -PKI_DEPLOYMENT_SCRIPTLETS_MODULE = "pki.deployment" -PKI_DEPLOYMENT_VERBOSITY=\ -"VERBOSITY FLAGS CONSOLE MESSAGE LEVEL LOG MESSAGE LEVEL\n"\ -"=======================================================================\n"\ -" NONE error|warning error|warning|info\n"\ -" -v error|warning|info error|warning|info\n"\ -" -vv error|warning|info error|warning|info|debug\n"\ -" -vvv error|warning|info|debug error|warning|info|debug\n"\ -" " PKI_DEPLOYMENT_DEFAULT_DIR_PERMISSIONS = 00770 PKI_DEPLOYMENT_DEFAULT_EXE_PERMISSIONS = 00770 PKI_DEPLOYMENT_DEFAULT_FILE_PERMISSIONS = 00660 +PKI_DEPLOYMENT_DEFAULT_SGID_DIR_PERMISSIONS = 02770 +PKI_DEPLOYMENT_DEFAULT_SYMLINK_PERMISSIONS = 00777 PKI_DEPLOYMENT_DEFAULT_UMASK = 00002 -PKIDESTROY_PATH = PKI_DEPLOYMENT_PATH + "/" + "destroy" -PKIDESTROY_LOG_PATH = "/var/log" -PKIDESTROY_LOG_PREFIX = "pki-" -PKIDESTROY_LOG_SUFFIX = "-destroy.log" -PKIDESTROY_LOGGER = "pkidestroy" - -PKIRESPAWN_PATH = PKI_DEPLOYMENT_PATH + "/" + "spawn" -PKIRESPAWN_LOG_PATH = "/var/log" -PKIRESPAWN_LOG_PREFIX = "pki-" -PKIRESPAWN_LOG_SUFFIX = "-respawn.log" -PKIRESPAWN_LOGGER = "pkirespawn" - -PKISPAWN_PATH = PKI_DEPLOYMENT_PATH + "/" + "spawn" -PKISPAWN_LOG_PATH = "/var/log" -PKISPAWN_LOG_PREFIX = "pki-" -PKISPAWN_LOG_SUFFIX = "-spawn.log" -PKISPAWN_LOGGER = "pkispawn" - -PKI_SECURITY_DATABASE_DIR = "alias" PKI_SUBSYSTEMS = ["CA","KRA","OCSP","RA","TKS","TPS"] +PKI_SIGNED_AUDIT_SUBSYSTEMS = ["CA","KRA","OCSP","TKS","TPS"] PKI_APACHE_SUBSYSTEMS = ["RA","TPS"] PKI_TOMCAT_SUBSYSTEMS = ["CA","KRA","OCSP","TKS"] +PKI_INDENTATION_LEVEL_0 = {'indent' : ''} +PKI_INDENTATION_LEVEL_1 = {'indent' : '... '} +PKI_INDENTATION_LEVEL_2 = {'indent' : '....... '} +PKI_INDENTATION_LEVEL_3 = {'indent' : '........... '} +PKI_INDENTATION_LEVEL_4 = {'indent' : '............... '} + +# NOTE: Well-known 'registry root', default 'instance', and default +# 'configuration file' names MUST be created in order to potentially +# obtain an instance-specific configuration file +# (presuming one has not been specified during command-line parsing) +# because command-line parsing happens prior to reading any +# configuration files. Although the 'registry root' MUST remain fixed, +# the default 'instance' name may be overridden by the value specified +# in the configuration file (the value in the default configuration file +# should always match the 'default' instance name specified below). +PKI_DEPLOYMENT_REGISTRY_ROOT = "/etc/sysconfig/pki" +PKI_DEPLOYMENT_DEFAULT_INSTANCE_NAME = "instance" +PKI_DEPLOYMENT_DEFAULT_CONFIGURATION_FILE = "pkideployment.cfg" + +# NOTE: Top-level "/etc/pki" is owned by the "filesystem" package! +PKI_SHARED_CONFIGURATION_ROOT = "/etc/pki" + + +# PKI Deployment Global Variables +pki_timestamp = None + # PKI Deployment "Mandatory" Command-Line Variables pki_subsystem = None # PKI Deployment "Optional" Command-Line Variables -pkideployment_cfg = PKI_DEPLOYMENT_CONFIG_PATH + "/" + "pkideployment.cfg" +pkideployment_cfg = "/usr/share/pki/deployment/config/pkideployment.cfg" pki_dry_run_flag = False pki_root_prefix = None pki_update_flag = False @@ -93,4 +92,3 @@ pki_common_dict = None pki_web_server_dict = None pki_subsystem_dict = None pki_master_dict = None - diff --git a/base/deploy/src/scriptlets/pkihelper.py b/base/deploy/src/scriptlets/pkihelper.py index ee2bdd249..95b5bf0a7 100644 --- a/base/deploy/src/scriptlets/pkihelper.py +++ b/base/deploy/src/scriptlets/pkihelper.py @@ -15,208 +15,1021 @@ # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -# Copyright (C) 2011 Red Hat, Inc. +# Copyright (C) 2012 Red Hat, Inc. # All rights reserved. # # System Imports -import ConfigParser -import argparse -import logging +import errno +import sys import os +import shutil +from grp import getgrnam +from pwd import getpwnam +import zipfile # PKI Deployment Imports import pkiconfig as config +from pkiconfig import pki_master_dict as master +import pkimanifest as manifest import pkimessages as log -# PKI Deployment Helper Functions -def process_command_line_arguments(argv): - "Read and process command-line options" - description = None - if os.path.basename(argv[0]) == 'pkispawn': - description = 'PKI Instance Installation and Configuration' - elif os.path.basename(argv[0]) == 'pkidestroy': - description = 'PKI Instance Removal' - parser = argparse.ArgumentParser( - description=description, - add_help=False, - formatter_class=argparse.RawDescriptionHelpFormatter, - epilog=config.PKI_DEPLOYMENT_VERBOSITY) - mandatory = parser.add_argument_group('mandatory arguments') - mandatory.add_argument('-s', - dest='pki_subsystem', action='store', - nargs=1, choices=config.PKI_SUBSYSTEMS, - required=True, metavar='', - help='where is ' - 'CA, KRA, OCSP, RA, TKS, or TPS') - optional = parser.add_argument_group('optional arguments') - optional.add_argument('--dry_run', - dest='pki_dry_run_flag', action='store_true', - help='do not actually perform any actions') - optional.add_argument('-f', - dest='pkideployment_cfg', action='store', - nargs=1, metavar='', - help='overrides default configuration filename') - optional.add_argument('-h', '--help', - dest='help', action='help', - help='show this help message and exit') - optional.add_argument('-p', - dest='pki_root_prefix', action='store', - nargs=1, metavar='', - help='directory prefix to specify local directory') - if os.path.basename(argv[0]) == 'pkispawn': - optional.add_argument('-u', - dest='pki_update_flag', action='store_true', - help='update instance of specified subsystem') - optional.add_argument('-v', - dest='pki_verbosity', action='count', - help='display verbose information (details below)') - custom = parser.add_argument_group('custom arguments ' - '(OVERRIDES configuration file values)') - custom.add_argument('-i', - dest='pki_instance_name', action='store', - nargs=1, metavar='', - help='PKI instance name (MUST specify REQUIRED ports)') - custom.add_argument('--http_port', - dest='pki_http_port', action='store', - nargs=1, metavar='', - help='HTTP port (CA, KRA, OCSP, RA, TKS, TPS)') - custom.add_argument('--https_port', - dest='pki_https_port', action='store', - nargs=1, metavar='', - help='HTTPS port (CA, KRA, OCSP, RA, TKS, TPS)') - custom.add_argument('--ajp_port', - dest='pki_ajp_port', action='store', - nargs=1, metavar='', - help='AJP port (CA, KRA, OCSP, TKS)') - args = parser.parse_args() - - config.pki_subsystem = str(args.pki_subsystem).strip('[\']') - if args.pki_dry_run_flag: - config.pki_dry_run_flag = args.pki_dry_run_flag - if not args.pkideployment_cfg is None: - config.pkideployment_cfg = str(args.pkideployment_cfg).strip('[\']') - if not os.path.exists(config.pkideployment_cfg) or\ - not os.path.isfile(config.pkideployment_cfg): - print "ERROR: " +\ - log.PKI_FILE_MISSING_OR_NOT_A_FILE_1 %\ - config.pkideployment_cfg - print - parser.print_help() - parser.exit(-1); - if not args.pki_root_prefix is None: - config.pki_root_prefix = str(args.pki_root_prefix).strip('[\']') - if config.pki_root_prefix is None or\ - len(config.pki_root_prefix) == 0: - config.pki_root_prefix = "" - elif not os.path.exists(config.pki_root_prefix) or\ - not os.path.isdir(config.pki_root_prefix): - print "ERROR: " +\ - log.PKI_DIRECTORY_MISSING_OR_NOT_A_DIRECTORY_1 %\ - config.pki_root_prefix - print - parser.print_help() - parser.exit(-1); - if os.path.basename(argv[0]) == 'pkispawn': - if args.pki_update_flag: - config.pki_update_flag = args.pki_update_flag - if args.pki_verbosity == 1: - config.pki_console_log_level = logging.INFO - config.pki_log_level = logging.INFO - elif args.pki_verbosity == 2: - config.pki_console_log_level = logging.INFO - config.pki_log_level = logging.DEBUG - elif args.pki_verbosity == 3: - config.pki_console_log_level = logging.DEBUG - config.pki_log_level = logging.DEBUG - elif args.pki_verbosity > 3: - print "ERROR: " + log.PKI_VERBOSITY_LEVELS_MESSAGE - print - parser.print_help() - parser.exit(-1); - if not args.pki_instance_name is None: - config.pki_instance_name = str(args.pki_instance_name).strip('[\']') - if not args.pki_http_port is None: - config.pki_http_port = str(args.pki_http_port).strip('[\']') - if not args.pki_https_port is None: - config.pki_https_port = str(args.pki_https_port).strip('[\']') - if not args.pki_ajp_port is None: - if config.pki_subsystem in config.PKI_TOMCAT_SUBSYSTEMS: - config.pki_ajp_port = str(args.pki_ajp_port).strip('[\']') - else: - print "ERROR: " +\ - log.PKI_CUSTOM_TOMCAT_AJP_PORT_1 %\ - config.pki_subsystem - print - parser.print_help() - parser.exit(-1); - if not args.pki_instance_name is None or\ - not args.pki_http_port is None or\ - not args.pki_https_port is None or\ - not args.pki_ajp_port is None: - if config.pki_subsystem in config.PKI_APACHE_SUBSYSTEMS: - if args.pki_instance_name is None or\ - args.pki_http_port is None or\ - args.pki_https_port is None: - print "ERROR: " + log.PKI_CUSTOM_APACHE_INSTANCE_1 %\ - config.pki_subsystem - print - parser.print_help() - parser.exit(-1); - elif config.pki_subsystem in config.PKI_TOMCAT_SUBSYSTEMS: - if args.pki_instance_name is None or\ - args.pki_http_port is None or\ - args.pki_https_port is None or\ - args.pki_ajp_port is None: - print "ERROR: " + log.PKI_CUSTOM_TOMCAT_INSTANCE_1 %\ - config.pki_subsystem - print - parser.print_help() - parser.exit(-1); - - -def read_pki_configuration_file(): - "Read configuration file sections into dictionaries" - rv = 0 +# PKI Deployment Functions +def pki_copytree(src, dst, symlinks=False, ignore=None): + """Recursively copy a directory tree using copy2(). + + PATCH: This code was copied from 'shutil.py' and patched to + allow 'The destination directory to already exist.' + + If exception(s) occur, an Error is raised with a list of reasons. + + If the optional symlinks flag is true, symbolic links in the + source tree result in symbolic links in the destination tree; if + it is false, the contents of the files pointed to by symbolic + links are copied. + + The optional ignore argument is a callable. If given, it + is called with the `src` parameter, which is the directory + being visited by pki_copytree(), and `names` which is the list of + `src` contents, as returned by os.listdir(): + + callable(src, names) -> ignored_names + + Since pki_copytree() is called recursively, the callable will be + called once for each directory that is copied. It returns a + list of names relative to the `src` directory that should + not be copied. + + XXX Consider this example code rather than the ultimate tool. + + """ + names = os.listdir(src) + if ignore is not None: + ignored_names = ignore(src, names) + else: + ignored_names = set() + + # PATCH: ONLY execute 'os.makedirs(dst)' if the top-level + # destination directory does NOT exist! + if not os.path.exists(dst): + os.makedirs(dst) + errors = [] + for name in names: + if name in ignored_names: + continue + srcname = os.path.join(src, name) + dstname = os.path.join(dst, name) + try: + if symlinks and os.path.islink(srcname): + linkto = os.readlink(srcname) + os.symlink(linkto, dstname) + elif os.path.isdir(srcname): + pki_copytree(srcname, dstname, symlinks, ignore) + else: + # Will raise a SpecialFileError for unsupported file types + shutil.copy2(srcname, dstname) + # catch the Error from the recursive pki_copytree so that we can + # continue with other files + except Error, err: + errors.extend(err.args[0]) + except EnvironmentError, why: + errors.append((srcname, dstname, str(why))) try: - parser = ConfigParser.ConfigParser() - parser.read(config.pkideployment_cfg) - config.pki_common_dict = dict(parser._sections['Common']) - if config.pki_subsystem == "CA": - config.pki_web_server_dict = dict(parser._sections['Tomcat']) - config.pki_subsystem_dict = dict(parser._sections['CA']) - elif config.pki_subsystem == "KRA": - config.pki_web_server_dict = dict(parser._sections['Tomcat']) - config.pki_subsystem_dict = dict(parser._sections['KRA']) - elif config.pki_subsystem == "OCSP": - config.pki_web_server_dict = dict(parser._sections['Tomcat']) - config.pki_subsystem_dict = dict(parser._sections['OCSP']) - elif config.pki_subsystem == "RA": - config.pki_web_server_dict = dict(parser._sections['Apache']) - config.pki_subsystem_dict = dict(parser._sections['RA']) - elif config.pki_subsystem == "TKS": - config.pki_web_server_dict = dict(parser._sections['Tomcat']) - config.pki_subsystem_dict = dict(parser._sections['TKS']) - elif config.pki_subsystem == "TPS": - config.pki_web_server_dict = dict(parser._sections['Apache']) - config.pki_subsystem_dict = dict(parser._sections['TPS']) - # Insert empty record into dictionaries for "pretty print" statements - config.pki_common_dict[0] = None - config.pki_web_server_dict[0] = None - config.pki_subsystem_dict[0] = None - except ConfigParser.ParsingError, err: - rv = err - return rv - - -def create_pki_master_dictionary(): - "Create a single master PKI dictionary from the sectional dictionaries" - config.pki_master_dict = dict() - config.pki_master_dict.update(config.pki_common_dict) - config.pki_master_dict.update(config.pki_web_server_dict) - config.pki_master_dict.update(config.pki_subsystem_dict) - config.pki_master_dict.update(__name__="PKI Master Dictionary") - return + shutil.copystat(src, dst) + except OSError, why: + if WindowsError is not None and isinstance(why, WindowsError): + # Copying file access times may fail on Windows + pass + else: + errors.extend((src, dst, str(why))) + if errors: + raise Error, errors + + +# PKI Deployment Identity Class +class identity: + def get_uid(self, critical_failure=True): + try: + pki_uid = master['pki_uid'] + except KeyError as exc: + config.pki_log.error(log.PKI_KEYERROR_1, exc, + extra=config.PKI_INDENTATION_LEVEL_2) + if critical_failure == True: + sys.exit(1) + return pki_uid + + def get_gid(self, critical_failure=True): + try: + pki_gid = master['pki_gid'] + except KeyError as exc: + config.pki_log.error(log.PKI_KEYERROR_1, exc, + extra=config.PKI_INDENTATION_LEVEL_2) + if critical_failure == True: + sys.exit(1) + return pki_gid + + def set_uid(self, name, critical_failure=True): + try: + config.pki_log.debug(log.PKIHELPER_USER_1, name, + extra=config.PKI_INDENTATION_LEVEL_2) + # id -u + pki_uid = getpwnam(name)[2] + master['pki_uid']=pki_uid + config.pki_log.debug(log.PKIHELPER_UID_2, name, pki_uid, + extra=config.PKI_INDENTATION_LEVEL_3) + except KeyError as exc: + config.pki_log.error(log.PKI_KEYERROR_1, exc, + extra=config.PKI_INDENTATION_LEVEL_2) + if critical_failure == True: + sys.exit(1) + return pki_uid + + def set_gid(self, name, critical_failure=True): + try: + config.pki_log.debug(log.PKIHELPER_GROUP_1, name, + extra=config.PKI_INDENTATION_LEVEL_2) + # id -g + pki_gid = getgrnam(name)[2] + master['pki_gid']=pki_gid + config.pki_log.debug(log.PKIHELPER_GID_2, name, pki_gid, + extra=config.PKI_INDENTATION_LEVEL_3) + except KeyError as exc: + config.pki_log.error(log.PKI_KEYERROR_1, exc, + extra=config.PKI_INDENTATION_LEVEL_2) + if critical_failure == True: + sys.exit(1) + return pki_gid + + +# PKI Deployment Instance Class +class instance: + def apache_instances(self, name): + rv = 0 + try: + if not os.path.exists(name) or not os.path.isdir(name): + config.pki_log.error( + log.PKI_DIRECTORY_MISSING_OR_NOT_A_DIRECTORY_1, name, + extra=config.PKI_INDENTATION_LEVEL_2) + sys.exit(1) + # count number of PKI subsystems present + # within the specfied Apache instance + for subsystem in config.PKI_APACHE_SUBSYSTEMS: + path = name + "/" + subsystem.lower() + if os.path.exists(path) and os.path.isdir(path): + rv = rv + 1 + # always display correct information (even during dry_run) + if config.pki_dry_run_flag and rv > 0: + config.pki_log.debug(log.PKIHELPER_APACHE_INSTANCES_2, + name, rv - 1, + extra=config.PKI_INDENTATION_LEVEL_2) + else: + config.pki_log.debug(log.PKIHELPER_APACHE_INSTANCES_2, name, + rv, extra=config.PKI_INDENTATION_LEVEL_2) + except OSError as exc: + config.pki_log.error(log.PKI_OSERROR_1, exc, + extra=config.PKI_INDENTATION_LEVEL_2) + sys.exit(1) + return rv + + def pki_subsystem_instances(self, name): + rv = 0 + try: + if not os.path.exists(name) or not os.path.isdir(name): + config.pki_log.error( + log.PKI_DIRECTORY_MISSING_OR_NOT_A_DIRECTORY_1, name, + extra=config.PKI_INDENTATION_LEVEL_2) + sys.exit(1) + # count total number of PKI subsystems present + # within the specfied PKI instance + for subsystem in config.PKI_SUBSYSTEMS: + path = name + "/" + subsystem.lower() + if os.path.exists(path) and os.path.isdir(path): + rv = rv + 1 + # always display correct information (even during dry_run) + if config.pki_dry_run_flag and rv > 0: + config.pki_log.debug(log.PKIHELPER_PKI_SUBSYSTEM_INSTANCES_2, + name, rv - 1, + extra=config.PKI_INDENTATION_LEVEL_2) + else: + config.pki_log.debug(log.PKIHELPER_PKI_SUBSYSTEM_INSTANCES_2, + name, rv, + extra=config.PKI_INDENTATION_LEVEL_2) + except OSError as exc: + config.pki_log.error(log.PKI_OSERROR_1, exc, + extra=config.PKI_INDENTATION_LEVEL_2) + sys.exit(1) + return rv + + def tomcat_instances(self, name): + rv = 0 + try: + if not os.path.exists(name) or not os.path.isdir(name): + config.pki_log.error( + log.PKI_DIRECTORY_MISSING_OR_NOT_A_DIRECTORY_1, name, + extra=config.PKI_INDENTATION_LEVEL_2) + sys.exit(1) + # count number of PKI subsystems present + # within the specfied Tomcat instance + for subsystem in config.PKI_TOMCAT_SUBSYSTEMS: + path = name + "/" + subsystem.lower() + if os.path.exists(path) and os.path.isdir(path): + rv = rv + 1 + # always display correct information (even during dry_run) + if config.pki_dry_run_flag and rv > 0: + config.pki_log.debug(log.PKIHELPER_TOMCAT_INSTANCES_2, + name, rv - 1, + extra=config.PKI_INDENTATION_LEVEL_2) + else: + config.pki_log.debug(log.PKIHELPER_TOMCAT_INSTANCES_2, name, + rv, extra=config.PKI_INDENTATION_LEVEL_2) + except OSError as exc: + config.pki_log.error(log.PKI_OSERROR_1, exc, + extra=config.PKI_INDENTATION_LEVEL_2) + sys.exit(1) + return rv + + +# PKI Deployment Directory Class +class directory: + def create(self, name, uid=None, gid=None, + perms=config.PKI_DEPLOYMENT_DEFAULT_DIR_PERMISSIONS, + acls=None, critical_failure=True): + try: + if not os.path.exists(name): + # mkdir -p + config.pki_log.info(log.PKIHELPER_MKDIR_1, name, + extra=config.PKI_INDENTATION_LEVEL_2) + if not config.pki_dry_run_flag: + os.makedirs(name) + # chmod + config.pki_log.debug(log.PKIHELPER_CHMOD_2, perms, name, + extra=config.PKI_INDENTATION_LEVEL_3) + if not config.pki_dry_run_flag: + os.chmod(name, perms) + # chown : + if uid == None: + uid = identity.get_uid() + if gid == None: + gid = identity.get_gid() + config.pki_log.debug(log.PKIHELPER_CHOWN_3, + uid, gid, name, + extra=config.PKI_INDENTATION_LEVEL_3) + if not config.pki_dry_run_flag: + os.chown(name, uid, gid) + # Store record in installation manifest + record = manifest.record() + record.name = name + record.type = manifest.RECORD_TYPE_DIRECTORY + record.user = master['pki_user'] + record.group = master['pki_group'] + record.uid = uid + record.gid = gid + record.permissions = perms + record.acls = acls + manifest.database.append(record) + elif not os.path.isdir(name): + config.pki_log.error( + log.PKI_DIRECTORY_ALREADY_EXISTS_NOT_A_DIRECTORY_1, name, + extra=config.PKI_INDENTATION_LEVEL_2) + if critical_failure == True: + sys.exit(1) + else: + config.pki_log.error(log.PKI_DIRECTORY_ALREADY_EXISTS_1, name, + extra=config.PKI_INDENTATION_LEVEL_2) + if critical_failure == True: + sys.exit(1) + except OSError as exc: + if exc.errno == errno.EEXIST: + pass + else: + config.pki_log.error(log.PKI_OSERROR_1, exc, + extra=config.PKI_INDENTATION_LEVEL_2) + if critical_failure == True: + sys.exit(1) + return + + def modify(self, name, uid=None, gid=None, + perms=config.PKI_DEPLOYMENT_DEFAULT_DIR_PERMISSIONS, + acls=None, silent=False, critical_failure=True): + try: + if os.path.exists(name): + if not os.path.isdir(name): + config.pki_log.error( + log.PKI_DIRECTORY_ALREADY_EXISTS_NOT_A_DIRECTORY_1, + name, extra=config.PKI_INDENTATION_LEVEL_2) + if critical_failure == True: + sys.exit(1) + # Always re-process each directory whether it needs it or not + if not silent: + config.pki_log.info(log.PKIHELPER_MODIFY_DIR_1, name, + extra=config.PKI_INDENTATION_LEVEL_2) + # chmod + if not silent: + config.pki_log.debug(log.PKIHELPER_CHMOD_2, perms, name, + extra=config.PKI_INDENTATION_LEVEL_3) + if not config.pki_dry_run_flag: + os.chmod(name, perms) + # chown : + if uid == None: + uid = identity.get_uid() + if gid == None: + gid = identity.get_gid() + if not silent: + config.pki_log.debug(log.PKIHELPER_CHOWN_3, + uid, gid, name, + extra=config.PKI_INDENTATION_LEVEL_3) + if not config.pki_dry_run_flag: + os.chown(name, uid, gid) + # Store record in installation manifest + if not silent: + record = manifest.record() + record.name = name + record.type = manifest.RECORD_TYPE_DIRECTORY + record.user = master['pki_user'] + record.group = master['pki_group'] + record.uid = uid + record.gid = gid + record.permissions = perms + record.acls = acls + manifest.database.append(record) + else: + config.pki_log.error( + log.PKI_DIRECTORY_MISSING_OR_NOT_A_DIRECTORY_1, name, + extra=config.PKI_INDENTATION_LEVEL_2) + if critical_failure == True: + sys.exit(1) + except OSError as exc: + config.pki_log.error(log.PKI_OSERROR_1, exc, + extra=config.PKI_INDENTATION_LEVEL_2) + if critical_failure == True: + sys.exit(1) + return + + def delete(self, name, recursive_flag=True, critical_failure=True): + try: + if not os.path.exists(name) or not os.path.isdir(name): + config.pki_log.error( + log.PKI_DIRECTORY_MISSING_OR_NOT_A_DIRECTORY_1, name, + extra=config.PKI_INDENTATION_LEVEL_2) + sys.exit(1) + else: + if recursive_flag == True: + # rm -rf + config.pki_log.info(log.PKIHELPER_RM_RF_1, name, + extra=config.PKI_INDENTATION_LEVEL_2) + if not config.pki_dry_run_flag: + shutil.rmtree(name) + else: + # rmdir + config.pki_log.info(log.PKIHELPER_RMDIR_1, name, + extra=config.PKI_INDENTATION_LEVEL_2) + if not config.pki_dry_run_flag: + os.rmdir(name) + except OSError as exc: + config.pki_log.error(log.PKI_OSERROR_1, exc, + extra=config.PKI_INDENTATION_LEVEL_2) + if critical_failure == True: + sys.exit(1) + return + + def is_empty(self, name): + try: + if not os.listdir(name): + config.pki_log.debug(log.PKIHELPER_DIRECTORY_IS_NOT_EMPTY_1, + name, extra=config.PKI_INDENTATION_LEVEL_2) + return False + else: + config.pki_log.debug(log.PKIHELPER_DIRECTORY_IS_EMPTY_1, + name, extra=config.PKI_INDENTATION_LEVEL_2) + return True + except OSError as exc: + config.pki_log.error(log.PKI_OSERROR_1, exc, + extra=config.PKI_INDENTATION_LEVEL_2) + sys.exit(1) + + def set_mode(self, name, uid=None, gid=None, + dir_perms=config.PKI_DEPLOYMENT_DEFAULT_DIR_PERMISSIONS, + file_perms=config.PKI_DEPLOYMENT_DEFAULT_FILE_PERMISSIONS, + symlink_perms=\ + config.PKI_DEPLOYMENT_DEFAULT_SYMLINK_PERMISSIONS, + dir_acls=None, file_acls=None, symlink_acls=None, + recursive_flag=True, critical_failure=True): + try: + if config.pki_dry_run_flag: + config.pki_log.info( + log.PKIHELPER_SET_MODE_1, name, + extra=config.PKI_INDENTATION_LEVEL_2) + elif not os.path.exists(name) or not os.path.isdir(name): + config.pki_log.error( + log.PKI_DIRECTORY_MISSING_OR_NOT_A_DIRECTORY_1, name, + extra=config.PKI_INDENTATION_LEVEL_2) + sys.exit(1) + else: + config.pki_log.info( + log.PKIHELPER_SET_MODE_1, name, + extra=config.PKI_INDENTATION_LEVEL_2) + if uid == None: + uid = identity.get_uid() + if gid == None: + gid = identity.get_gid() + if recursive_flag == True: + for root, dirs, files in os.walk(name): + for name in files: + if not os.path.islink(name): + file = os.path.join(root, name) + config.pki_log.debug( + log.PKIHELPER_IS_A_FILE_1, file, + extra=config.PKI_INDENTATION_LEVEL_3) + # chmod + config.pki_log.debug(log.PKIHELPER_CHMOD_2, + file_perms, file, + extra=config.PKI_INDENTATION_LEVEL_3) + if not config.pki_dry_run_flag: + os.chmod(file, file_perms) + # chown : + config.pki_log.debug(log.PKIHELPER_CHOWN_3, + uid, gid, file, + extra=config.PKI_INDENTATION_LEVEL_3) + if not config.pki_dry_run_flag: + os.chown(file, uid, gid) + # Store record in installation manifest + record = manifest.record() + record.name = name + record.type = manifest.RECORD_TYPE_FILE + record.user = master['pki_user'] + record.group = master['pki_group'] + record.uid = uid + record.gid = gid + record.permissions = file_perms + record.acls = file_acls + manifest.database.append(record) + else: + symlink = os.path.join(root, name) + config.pki_log.debug( + log.PKIHELPER_IS_A_SYMLINK_1, symlink, + extra=config.PKI_INDENTATION_LEVEL_3) + # REMINDER: Due to POSIX compliance, 'lchmod' + # is NEVER implemented on Linux + # systems since 'chmod' CANNOT be + # run directly against symbolic + # links! + # chown -h : + config.pki_log.debug(log.PKIHELPER_CHOWN_H_3, + uid, gid, link, + extra=config.PKI_INDENTATION_LEVEL_3) + if not config.pki_dry_run_flag: + os.lchown(link, uid, gid) + # Store record in installation manifest + record = manifest.record() + record.name = name + record.type = manifest.RECORD_TYPE_SYMLINK + record.user = master['pki_user'] + record.group = master['pki_group'] + record.uid = uid + record.gid = gid + record.permissions = symlink_perms + record.acls = symlink_acls + manifest.database.append(record) + for name in dirs: + dir = os.path.join(root, name) + config.pki_log.debug( + log.PKIHELPER_IS_A_DIRECTORY_1, dir, + extra=config.PKI_INDENTATION_LEVEL_3) + # chmod + config.pki_log.debug(log.PKIHELPER_CHMOD_2, + dir_perms, dir, + extra=config.PKI_INDENTATION_LEVEL_3) + if not config.pki_dry_run_flag: + os.chmod(dir, dir_perms) + # chown : + config.pki_log.debug(log.PKIHELPER_CHOWN_3, + uid, gid, dir, + extra=config.PKI_INDENTATION_LEVEL_3) + if not config.pki_dry_run_flag: + os.chown(dir, uid, gid) + # Store record in installation manifest + record = manifest.record() + record.name = name + record.type = manifest.RECORD_TYPE_DIRECTORY + record.user = master['pki_user'] + record.group = master['pki_group'] + record.uid = uid + record.gid = gid + record.permissions = dir_perms + record.acls = dir_acls + manifest.database.append(record) + else: + config.pki_log.debug( + log.PKIHELPER_IS_A_DIRECTORY_1, name, + extra=config.PKI_INDENTATION_LEVEL_3) + name = os.path.join(root, name) + # chmod + config.pki_log.debug(log.PKIHELPER_CHMOD_2, + dir_perms, name, + extra=config.PKI_INDENTATION_LEVEL_3) + if not config.pki_dry_run_flag: + os.chmod(name, dir_perms) + # chown : + config.pki_log.debug(log.PKIHELPER_CHOWN_3, + uid, gid, name, + extra=config.PKI_INDENTATION_LEVEL_3) + if not config.pki_dry_run_flag: + os.chown(name, uid, gid) + # Store record in installation manifest + record = manifest.record() + record.name = name + record.type = manifest.RECORD_TYPE_DIRECTORY + record.user = master['pki_user'] + record.group = master['pki_group'] + record.uid = uid + record.gid = gid + record.permissions = dir_perms + record.acls = dir_acls + manifest.database.append(record) + except OSError as exc: + config.pki_log.error(log.PKI_OSERROR_1, exc, + extra=config.PKI_INDENTATION_LEVEL_2) + if critical_failure == True: + sys.exit(1) + + def copy(self, old_name, new_name, uid=None, gid=None, + dir_perms=config.PKI_DEPLOYMENT_DEFAULT_DIR_PERMISSIONS, + file_perms=config.PKI_DEPLOYMENT_DEFAULT_FILE_PERMISSIONS, + symlink_perms=config.PKI_DEPLOYMENT_DEFAULT_SYMLINK_PERMISSIONS, + dir_acls=None, file_acls=None, symlink_acls=None, + recursive_flag=True, overwrite_flag=False, critical_failure=True): + try: + if not os.path.exists(old_name) or not os.path.isdir(old_name): + config.pki_log.error( + log.PKI_DIRECTORY_MISSING_OR_NOT_A_DIRECTORY_1, old_name, + extra=config.PKI_INDENTATION_LEVEL_2) + sys.exit(1) + elif config.pki_dry_run_flag: + if recursive_flag == True: + # cp -rp + config.pki_log.info(log.PKIHELPER_CP_RP_2, + old_name, new_name, + extra=config.PKI_INDENTATION_LEVEL_2) + else: + # cp -p + config.pki_log.info(log.PKIHELPER_CP_P_2, + old_name, new_name, + extra=config.PKI_INDENTATION_LEVEL_2) + config.pki_log.info( + log.PKIHELPER_SET_MODE_1, new_name, + extra=config.PKI_INDENTATION_LEVEL_2) + else: + if os.path.exists(new_name): + if not overwrite_flag: + config.pki_log.error( + log.PKI_DIRECTORY_ALREADY_EXISTS_1, new_name, + extra=config.PKI_INDENTATION_LEVEL_2) + sys.exit(1) + if recursive_flag == True: + # cp -rp + config.pki_log.info(log.PKIHELPER_CP_RP_2, + old_name, new_name, + extra=config.PKI_INDENTATION_LEVEL_2) + # Due to a limitation in the 'shutil.copytree()' + # implementation which requires that + # 'The destination directory must not already exist.', + # an OSError exception is always thrown due to the + # implementation's unchecked call to 'os.makedirs(dst)'. + # Consequently, a 'patched' local copy of this routine has + # been included in this file with the appropriate fix. + pki_copytree(old_name, new_name) + else: + # cp -p + config.pki_log.info(log.PKIHELPER_CP_P_2, + old_name, new_name, + extra=config.PKI_INDENTATION_LEVEL_2) + shutil.copy2(old_name, new_name) + # set ownerships, permissions, and acls + # of newly created top-level directory + self.modify(new_name, uid, gid, dir_perms, dir_acls, + True, critical_failure) + # set ownerships, permissions, and acls + # of contents of newly created top-level directory + self.set_mode(new_name, uid, gid, + dir_perms, file_perms, symlink_perms, + dir_acls, file_acls, symlink_acls, + recursive_flag, critical_failure) + except OSError as exc: + config.pki_log.error(log.PKI_OSERROR_1, exc, + extra=config.PKI_INDENTATION_LEVEL_2) + if critical_failure == True: + sys.exit(1) + except shutil.Error as exc: + config.pki_log.error(log.PKI_SHUTIL_ERROR_1, exc, + extra=config.PKI_INDENTATION_LEVEL_2) + if critical_failure == True: + sys.exit(1) + return + + +# PKI Deployment File Class (also used for executables) +class file: + def create(self, name, uid=None, gid=None, + perms=config.PKI_DEPLOYMENT_DEFAULT_FILE_PERMISSIONS, + acls=None, critical_failure=True): + try: + if not os.path.exists(name): + # touch + config.pki_log.info(log.PKIHELPER_TOUCH_1, name, + extra=config.PKI_INDENTATION_LEVEL_2) + if not config.pki_dry_run_flag: + open(name, "w").close() + # chmod + config.pki_log.debug(log.PKIHELPER_CHMOD_2, perms, name, + extra=config.PKI_INDENTATION_LEVEL_3) + if not config.pki_dry_run_flag: + os.chmod(name, perms) + # chown : + if uid == None: + uid = identity.get_uid() + if gid == None: + gid = identity.get_gid() + config.pki_log.debug(log.PKIHELPER_CHOWN_3, + uid, gid, name, + extra=config.PKI_INDENTATION_LEVEL_3) + if not config.pki_dry_run_flag: + os.chown(name, uid, gid) + # Store record in installation manifest + record = manifest.record() + record.name = name + record.type = manifest.RECORD_TYPE_FILE + record.user = master['pki_user'] + record.group = master['pki_group'] + record.uid = uid + record.gid = gid + record.permissions = perms + record.acls = acls + manifest.database.append(record) + elif not os.path.isfile(name): + config.pki_log.error( + log.PKI_FILE_ALREADY_EXISTS_NOT_A_FILE_1, name, + extra=config.PKI_INDENTATION_LEVEL_2) + if critical_failure == True: + sys.exit(1) + else: + config.pki_log.error(log.PKI_FILE_ALREADY_EXISTS_1, name, + extra=config.PKI_INDENTATION_LEVEL_2) + if critical_failure == True: + sys.exit(1) + except OSError as exc: + if exc.errno == errno.EEXIST: + pass + else: + config.pki_log.error(log.PKI_OSERROR_1, exc, + extra=config.PKI_INDENTATION_LEVEL_2) + if critical_failure == True: + sys.exit(1) + return + + def modify(self, name, uid=None, gid=None, + perms=config.PKI_DEPLOYMENT_DEFAULT_FILE_PERMISSIONS, + acls=None, silent=False, critical_failure=True): + try: + if os.path.exists(name): + if not os.path.isfile(name): + config.pki_log.error( + log.PKI_FILE_ALREADY_EXISTS_NOT_A_FILE_1, + name, extra=config.PKI_INDENTATION_LEVEL_2) + if critical_failure == True: + sys.exit(1) + # Always re-process each file whether it needs it or not + if not silent: + config.pki_log.info(log.PKIHELPER_MODIFY_FILE_1, name, + extra=config.PKI_INDENTATION_LEVEL_2) + # chmod + if not silent: + config.pki_log.debug(log.PKIHELPER_CHMOD_2, perms, name, + extra=config.PKI_INDENTATION_LEVEL_3) + if not config.pki_dry_run_flag: + os.chmod(name, perms) + # chown : + if uid == None: + uid = identity.get_uid() + if gid == None: + gid = identity.get_gid() + if not silent: + config.pki_log.debug(log.PKIHELPER_CHOWN_3, + uid, gid, name, + extra=config.PKI_INDENTATION_LEVEL_3) + if not config.pki_dry_run_flag: + os.chown(name, uid, gid) + # Store record in installation manifest + if not silent: + record = manifest.record() + record.name = name + record.type = manifest.RECORD_TYPE_FILE + record.user = master['pki_user'] + record.group = master['pki_group'] + record.uid = uid + record.gid = gid + record.permissions = perms + record.acls = acls + manifest.database.append(record) + else: + config.pki_log.error( + log.PKI_FILE_MISSING_OR_NOT_A_FILE_1, name, + extra=config.PKI_INDENTATION_LEVEL_2) + if critical_failure == True: + sys.exit(1) + except OSError as exc: + config.pki_log.error(log.PKI_OSERROR_1, exc, + extra=config.PKI_INDENTATION_LEVEL_2) + if critical_failure == True: + sys.exit(1) + return + + def delete(self, name, critical_failure=True): + try: + if not os.path.exists(name) or not os.path.isfile(name): + config.pki_log.error( + log.PKI_FILE_MISSING_OR_NOT_A_FILE_1, name, + extra=config.PKI_INDENTATION_LEVEL_2) + sys.exit(1) + else: + # rm -f + config.pki_log.info(log.PKIHELPER_RM_F_1, name, + extra=config.PKI_INDENTATION_LEVEL_2) + if not config.pki_dry_run_flag: + os.remove(name) + except OSError as exc: + config.pki_log.error(log.PKI_OSERROR_1, exc, + extra=config.PKI_INDENTATION_LEVEL_2) + if critical_failure == True: + sys.exit(1) + return + + def copy(self, old_name, new_name, uid=None, gid=None, + perms=config.PKI_DEPLOYMENT_DEFAULT_FILE_PERMISSIONS, acls=None, + overwrite_flag=False, critical_failure=True): + try: + if not os.path.exists(old_name) or not os.path.isfile(old_name): + config.pki_log.error( + log.PKI_FILE_MISSING_OR_NOT_A_FILE_1, old_name, + extra=config.PKI_INDENTATION_LEVEL_2) + sys.exit(1) + elif config.pki_dry_run_flag: + # cp -p + config.pki_log.info(log.PKIHELPER_CP_P_2, + old_name, new_name, + extra=config.PKI_INDENTATION_LEVEL_2) + # chmod + config.pki_log.debug(log.PKIHELPER_CHMOD_2, + perms, new_name, + extra=config.PKI_INDENTATION_LEVEL_3) + # chown : + config.pki_log.debug(log.PKIHELPER_CHOWN_3, + uid, gid, new_name, + extra=config.PKI_INDENTATION_LEVEL_3) + else: + if os.path.exists(new_name): + if not overwrite_flag: + config.pki_log.error( + log.PKI_FILE_ALREADY_EXISTS_1, new_name, + extra=config.PKI_INDENTATION_LEVEL_2) + sys.exit(1) + # cp -p + config.pki_log.info(log.PKIHELPER_CP_P_2, + old_name, new_name, + extra=config.PKI_INDENTATION_LEVEL_2) + shutil.copy2(old_name, new_name) + if uid == None: + uid = identity.get_uid() + if gid == None: + gid = identity.get_gid() + # chmod + config.pki_log.debug(log.PKIHELPER_CHMOD_2, + perms, new_name, + extra=config.PKI_INDENTATION_LEVEL_3) + os.chmod(new_name, perms) + # chown : + config.pki_log.debug(log.PKIHELPER_CHOWN_3, + uid, gid, new_name, + extra=config.PKI_INDENTATION_LEVEL_3) + os.chown(new_name, uid, gid) + # Store record in installation manifest + record = manifest.record() + record.name = new_name + record.type = manifest.RECORD_TYPE_FILE + record.user = master['pki_user'] + record.group = master['pki_group'] + record.uid = uid + record.gid = gid + record.permissions = perms + record.acls = acls + manifest.database.append(record) + except OSError as exc: + config.pki_log.error(log.PKI_OSERROR_1, exc, + extra=config.PKI_INDENTATION_LEVEL_2) + if critical_failure == True: + sys.exit(1) + except shutil.Error as exc: + config.pki_log.error(log.PKI_SHUTIL_ERROR_1, exc, + extra=config.PKI_INDENTATION_LEVEL_2) + if critical_failure == True: + sys.exit(1) + return + + +# PKI Deployment Symbolic Link Class +class symlink: + def create(self, name, link, uid=None, gid=None, + acls=None, allow_dangling_symlink=False, critical_failure=True): + try: + if not os.path.exists(link): + if not config.pki_dry_run_flag: + if not os.path.exists(name): + config.pki_log.warning( + log.PKIHELPER_DANGLING_SYMLINK_2, link, name, + extra=config.PKI_INDENTATION_LEVEL_2) + if not allow_dangling_symlink: + sys.exit(1) + # ln -s + config.pki_log.info(log.PKIHELPER_LINK_S_2, name, link, + extra=config.PKI_INDENTATION_LEVEL_2) + if not config.pki_dry_run_flag: + os.symlink(name, link) + # REMINDER: Due to POSIX compliance, 'lchmod' is NEVER + # implemented on Linux systems since 'chmod' + # CANNOT be run directly against symbolic links! + # chown -h : + if uid == None: + uid = identity.get_uid() + if gid == None: + gid = identity.get_gid() + config.pki_log.debug(log.PKIHELPER_CHOWN_H_3, + uid, gid, link, + extra=config.PKI_INDENTATION_LEVEL_3) + if not config.pki_dry_run_flag: + os.lchown(link, uid, gid) + # Store record in installation manifest + record = manifest.record() + record.name = link + record.type = manifest.RECORD_TYPE_SYMLINK + record.user = master['pki_user'] + record.group = master['pki_group'] + record.uid = uid + record.gid = gid + record.permissions =\ + config.PKI_DEPLOYMENT_DEFAULT_SYMLINK_PERMISSIONS + record.acls = acls + manifest.database.append(record) + elif not os.path.islink(link): + config.pki_log.error( + log.PKI_SYMLINK_ALREADY_EXISTS_NOT_A_SYMLINK_1, link, + extra=config.PKI_INDENTATION_LEVEL_2) + if critical_failure == True: + sys.exit(1) + else: + config.pki_log.error(log.PKI_SYMLINK_ALREADY_EXISTS_1, link, + extra=config.PKI_INDENTATION_LEVEL_2) + if critical_failure == True: + sys.exit(1) + except OSError as exc: + if exc.errno == errno.EEXIST: + pass + else: + config.pki_log.error(log.PKI_OSERROR_1, exc, + extra=config.PKI_INDENTATION_LEVEL_2) + if critical_failure == True: + sys.exit(1) + return + + def modify(self, link, uid=None, gid=None, + acls=None, silent=False, critical_failure=True): + try: + if os.path.exists(link): + if not os.path.islink(link): + config.pki_log.error( + log.PKI_SYMLINK_ALREADY_EXISTS_NOT_A_SYMLINK_1, + link, extra=config.PKI_INDENTATION_LEVEL_2) + if critical_failure == True: + sys.exit(1) + # Always re-process each link whether it needs it or not + if not silent: + config.pki_log.info(log.PKIHELPER_MODIFY_SYMLINK_1, link, + extra=config.PKI_INDENTATION_LEVEL_2) + # REMINDER: Due to POSIX compliance, 'lchmod' is NEVER + # implemented on Linux systems since 'chmod' + # CANNOT be run directly against symbolic links! + # chown -h : + if uid == None: + uid = identity.get_uid() + if gid == None: + gid = identity.get_gid() + if not silent: + config.pki_log.debug(log.PKIHELPER_CHOWN_H_3, + uid, gid, link, + extra=config.PKI_INDENTATION_LEVEL_3) + if not config.pki_dry_run_flag: + os.lchown(link, uid, gid) + # Store record in installation manifest + if not silent: + record = manifest.record() + record.name = link + record.type = manifest.RECORD_TYPE_SYMLINK + record.user = master['pki_user'] + record.group = master['pki_group'] + record.uid = uid + record.gid = gid + record.permissions =\ + config.PKI_DEPLOYMENT_DEFAULT_SYMLINK_PERMISSIONS + record.acls = acls + manifest.database.append(record) + else: + config.pki_log.error( + log.PKI_SYMLINK_MISSING_OR_NOT_A_SYMLINK_1, link, + extra=config.PKI_INDENTATION_LEVEL_2) + if critical_failure == True: + sys.exit(1) + except OSError as exc: + config.pki_log.error(log.PKI_OSERROR_1, exc, + extra=config.PKI_INDENTATION_LEVEL_2) + if critical_failure == True: + sys.exit(1) + return + + def delete(self, link, critical_failure=True): + try: + if not os.path.exists(link) or not os.path.islink(link): + config.pki_log.error( + log.PKI_SYMLINK_MISSING_OR_NOT_A_SYMLINK_1, link, + extra=config.PKI_INDENTATION_LEVEL_2) + sys.exit(1) + else: + # rm -f + config.pki_log.info(log.PKIHELPER_RM_F_1, link, + extra=config.PKI_INDENTATION_LEVEL_2) + if not config.pki_dry_run_flag: + os.remove(link) + except OSError as exc: + config.pki_log.error(log.PKI_OSERROR_1, exc, + extra=config.PKI_INDENTATION_LEVEL_2) + if critical_failure == True: + sys.exit(1) + return + + +# PKI Deployment War File Class +class war: + def explode(self, name, path, critical_failure=True): + try: + if os.path.exists(name) and os.path.isfile(name): + if not zipfile.is_zipfile(name): + config.pki_log.error( + log.PKI_FILE_NOT_A_WAR_FILE_1, + name, extra=config.PKI_INDENTATION_LEVEL_2) + if critical_failure == True: + sys.exit(1) + if not config.pki_dry_run_flag: + if not os.path.exists(path) or not os.path.isdir(path): + config.pki_log.error( + log.PKI_DIRECTORY_MISSING_OR_NOT_A_DIRECTORY_1, + path, extra=config.PKI_INDENTATION_LEVEL_2) + if critical_failure == True: + sys.exit(1) + # jar -xf -C + config.pki_log.info(log.PKIHELPER_JAR_XF_C_2, name, path, + extra=config.PKI_INDENTATION_LEVEL_2) + if not config.pki_dry_run_flag: + # Open war file + war = zipfile.ZipFile(name, 'r') + # Extract contents of war file to path + war.extractall(path) + else: + config.pki_log.error( + log.PKI_FILE_MISSING_OR_NOT_A_FILE_1, name, + extra=config.PKI_INDENTATION_LEVEL_2) + if critical_failure == True: + sys.exit(1) + except OSError as exc: + config.pki_log.error(log.PKI_OSERROR_1, exc, + extra=config.PKI_INDENTATION_LEVEL_2) + if critical_failure == True: + sys.exit(1) + except zipfile.BadZipfile as exc: + config.pki_log.error(log.PKI_BADZIPFILE_ERROR_1, exc, + extra=config.PKI_INDENTATION_LEVEL_2) + if critical_failure == True: + sys.exit(1) + except zipfile.LargeZipFile as exc: + config.pki_log.error(log.PKI_LARGEZIPFILE_ERROR_1, exc, + extra=config.PKI_INDENTATION_LEVEL_2) + if critical_failure == True: + sys.exit(1) + return + +# PKI Deployment Helper Class Instances +identity = identity() +instance = instance() +directory = directory() +file = file() +symlink = symlink() +war = war() diff --git a/base/deploy/src/scriptlets/pkilogging.py b/base/deploy/src/scriptlets/pkilogging.py index 776677cfd..9b22ae39c 100644 --- a/base/deploy/src/scriptlets/pkilogging.py +++ b/base/deploy/src/scriptlets/pkilogging.py @@ -15,7 +15,7 @@ # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -# Copyright (C) 2011 Red Hat, Inc. +# Copyright (C) 2012 Red Hat, Inc. # All rights reserved. # @@ -31,16 +31,36 @@ def enable_pki_logger(log_dir, log_name, log_level, console_log_level, logger): os.makedirs(log_dir) except OSError: return OSError + + # Establish 'file' logger using 'basicConfig()' + logging.LoggerAdapter(logging.getLogger(''), {'indent' : ''}) logging.basicConfig(level=log_level, format='%(asctime)s %(name)-12s ' +\ - '%(levelname)-8s %(message)s', + '%(levelname)-8s ' +\ + '%(indent)s%(message)s', datefmt='%Y-%m-%d %H:%M:%S', filename=log_dir + "/" + log_name, filemode='w') + + # Establish 'console' logger console = logging.StreamHandler() + logging.LoggerAdapter(console, {'indent' : ''}) console.setLevel(console_log_level) - formatter = logging.Formatter('%(name)-12s: %(levelname)-8s %(message)s') - console.setFormatter(formatter) + console_format = logging.Formatter('%(name)-12s: ' +\ + '%(levelname)-8s ' +\ + '%(indent)s%(message)s') + console.setFormatter(console_format) logging.getLogger('').addHandler(console) - return logging.getLogger(logger) + # Establish 'file' logger +# file = logging.FileHandler(log_dir + "/" + log_name, 'w') +# logging.LoggerAdapter(file, {'indent' : ''}) +# file.setLevel(log_level) +# file_format = logging.Formatter('%(asctime)s %(name)-12s: ' +\ +# '%(levelname)-8s ' +\ +# '%(indent)s%(message)s', +# '%Y-%m-%d %H:%M:%S') +# file.setFormatter(file_format) +# logging.getLogger('').addHandler(file) + + return logging.getLogger(logger) diff --git a/base/deploy/src/scriptlets/pkimanifest.py b/base/deploy/src/scriptlets/pkimanifest.py new file mode 100644 index 000000000..dfd18fbaf --- /dev/null +++ b/base/deploy/src/scriptlets/pkimanifest.py @@ -0,0 +1,97 @@ +#!/usr/bin/python -t +# Authors: +# Matthew Harmsen +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; version 2 of the License. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Copyright (C) 2012 Red Hat, Inc. +# All rights reserved. +# + +# System Imports +from collections import namedtuple +import csv + + +# PKI Deployment Manifest Constants +RECORD_TYPE_DIRECTORY = "directory" +RECORD_TYPE_FILE = "file" +RECORD_TYPE_SYMLINK = "symlink" + + +# PKI Deployment Manifest Record Class +class record(object): + __slots__= "name",\ + "type",\ + "user",\ + "group",\ + "uid",\ + "gid",\ + "permissions",\ + "acls", + + def items(self): + "dict style items" + return [ + (field_name, getattr(self, field_name)) + for field_name in self.__slots__] + + def __iter__(self): + "iterate over fields tuple/list style" + for field_name in self.__slots__: + yield getattr(self, field_name) + + def __getitem__(self, index): + "tuple/list style getitem" + return getattr(self, self.__slots__[index]) + + +# PKI Deployment Manifest File Class +class file: + """FUTURE: Consider creating a single manifest file + that is always overwritten.""" + global database + filename = None + + def register(self, name): + self.filename = name + + def write(self): + try: + fd = open(self.filename, "wt") + c = csv.writer(fd) + for record in database: + c.writerow(tuple(record)) + fd.close() + except IOError as exc: + config.pki_log.error(log.PKI_IOERROR_1, exc, + extra=config.PKI_INDENTATION_LEVEL_1) + sys.exit(1) + + def read(self): + try: + fd = open(self.filename, "rt") + cr = csv.reader(fd) + for row in cr: + print tuple(row) + fd.close() + except IOError as exc: + config.pki_log.error(log.PKI_IOERROR_1, exc, + extra=config.PKI_INDENTATION_LEVEL_1) + sys.exit(1) + + +# PKI Deployment Global Named Tuples +database = [] +file = file() diff --git a/base/deploy/src/scriptlets/pkimessages.py b/base/deploy/src/scriptlets/pkimessages.py index e6a9f95aa..81f0eadfe 100644 --- a/base/deploy/src/scriptlets/pkimessages.py +++ b/base/deploy/src/scriptlets/pkimessages.py @@ -15,22 +15,11 @@ # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -# Copyright (C) 2011 Red Hat, Inc. +# Copyright (C) 2012 Red Hat, Inc. # All rights reserved. # # PKI Deployment Engine Messages -PKI_CUSTOM_APACHE_INSTANCE_1 = "When a custom '%s' subsystem is being "\ - "deployed, the 'instance', 'http_port', and "\ - "'https_port' must ALL be specified!" -PKI_CUSTOM_TOMCAT_INSTANCE_1 = "When a custom '%s' subsystem is being "\ - "deployed, the 'instance', 'http_port', "\ - "'https_port', and 'ajp_port' must ALL be "\ - "specified!" -PKI_CUSTOM_TOMCAT_AJP_PORT_1 = "When a custom '%s' subsystem is being "\ - "deployed, ONLY the 'instance', "\ - "'http_port', and 'https_port' MUST be "\ - "specified; NO 'ajp_port' should be requested!" PKI_DICTIONARY_COMMON ="\n"\ "=====================================================\n"\ " DISPLAY CONTENTS OF PKI COMMON DICTIONARY\n"\ @@ -47,14 +36,57 @@ PKI_DICTIONARY_WEB_SERVER="\n"\ "=====================================================\n"\ " DISPLAY CONTENTS OF PKI WEB SERVER DICTIONARY\n"\ "=====================================================" + + +# PKI Deployment Log Messages +PKI_VERBOSITY=\ +"VERBOSITY FLAGS CONSOLE MESSAGE LEVEL LOG MESSAGE LEVEL\n"\ +"=======================================================================\n"\ +" NONE error|warning error|warning|info\n"\ +" -v error|warning|info error|warning|info\n"\ +" -vv error|warning|info error|warning|info|debug\n"\ +" -vvv error|warning|info|debug error|warning|info|debug\n"\ +" " + +# PKI Deployment Error Messages +PKI_BADZIPFILE_ERROR_1 = "zipfile.BadZipFile: %s!" +PKI_CUSTOM_APACHE_INSTANCE_1 = "When a custom '%s' subsystem is being "\ + "deployed, the 'instance', 'http_port', and "\ + "'https_port' must ALL be specified!" +PKI_CUSTOM_TOMCAT_INSTANCE_1 = "When a custom '%s' subsystem is being "\ + "deployed, the 'instance', 'http_port', "\ + "'https_port', and 'ajp_port' must ALL be "\ + "specified!" +PKI_CUSTOM_TOMCAT_AJP_PORT_1 = "When a custom '%s' subsystem is being "\ + "deployed, ONLY the 'instance', "\ + "'http_port', and 'https_port' MUST be "\ + "specified; NO 'ajp_port' should be requested!" PKI_DIRECTORY_ALREADY_EXISTS_1 = "Directory '%s' already exists!" PKI_DIRECTORY_ALREADY_EXISTS_NOT_A_DIRECTORY_1 = "Directory '%s' already "\ "exists BUT it is NOT a "\ "directory!" PKI_DIRECTORY_MISSING_OR_NOT_A_DIRECTORY_1 = "Directory '%s' is either "\ "missing or is NOT a directory!" +PKI_FILE_ALREADY_EXISTS_1 = "File '%s' already exists!" +PKI_FILE_ALREADY_EXISTS_NOT_A_FILE_1 = "File '%s' already "\ + "exists BUT it is NOT a "\ + "file!" PKI_FILE_MISSING_OR_NOT_A_FILE_1 = "File '%s' is either missing "\ "or is NOT a regular file!" +PKI_FILE_NOT_A_WAR_FILE_1 = "File '%s' is NOT a war file!" + +PKI_IOERROR_1 = "IOError: %s!" +PKI_KEYERROR_1 = "KeyError: %s!" +PKI_LARGEZIPFILE_ERROR_1 = "zipfile.LargeZipFile: %s!" +PKI_MANIFEST_MESSAGE_1 = "generating manifest file called '%s'" +PKI_OSERROR_1 = "OSError: %s!" +PKI_SHUTIL_ERROR_1 = "shutil.Error: %s!" +PKI_SYMLINK_ALREADY_EXISTS_1 = "Symlink '%s' already exists!" +PKI_SYMLINK_ALREADY_EXISTS_NOT_A_SYMLINK_1 = "Symlink '%s' already "\ + "exists BUT it is NOT a "\ + "symlink!" +PKI_SYMLINK_MISSING_OR_NOT_A_SYMLINK_1 = "Symlink '%s' is either missing "\ + "or is NOT a symbolic link!" PKI_UNABLE_TO_PARSE_1 = "'Could not parse: '%s'" PKI_UNABLE_TO_CREATE_LOG_DIRECTORY_1 = "Could not create log directory '%s'!" PKI_VERBOSITY_LEVELS_MESSAGE = "Only up to 3 levels of verbosity are supported!" @@ -64,23 +96,77 @@ PKI_VERBOSITY_LEVELS_MESSAGE = "Only up to 3 levels of verbosity are supported!" PKIDESTROY_BEGIN_MESSAGE_2 = "BEGIN destroying subsystem '%s' of "\ "instance '%s' . . ." PKIDESTROY_END_MESSAGE_2 = "END destroying subsystem '%s' of "\ - "instance '%s'." + "instance '%s'" PKIRESPAWN_BEGIN_MESSAGE_2 = "BEGIN respawning subsystem '%s' of "\ "instance '%s' . . ." PKIRESPAWN_END_MESSAGE_2 = "END respawning subsystem '%s' of "\ - "instance '%s'." + "instance '%s'" PKISPAWN_BEGIN_MESSAGE_2 = "BEGIN spawning subsystem '%s' of "\ "instance '%s' . . ." PKISPAWN_END_MESSAGE_2 = "END spawning subsystem '%s' of "\ - "instance '%s'." + "instance '%s'" -# PKI Deployment "Scriptlet" Messages -INSTANCE_DESTROY_1 = " depopulating '%s'" -INSTANCE_RESPAWN_1 = " repopulating '%s'" -INSTANCE_SPAWN_1 = " populating '%s'" -INSTANCE_SPAWN_MKDIR_1 = " mkdir '%s'" -SECURITY_DATABASES_DESTROY_1 = " removing '%s'" -SECURITY_DATABASES_RESPAWN_1 = " regenerating '%s'" -SECURITY_DATABASES_SPAWN_1 = " generating '%s'" +# PKI Deployment "Helper" Messages +PKIHELPER_APACHE_INSTANCES_2 = "instance '%s' contains '%d' Apache PKI subsystems" +PKIHELPER_CHMOD_2 = "chmod %o %s" +PKIHELPER_CHOWN_3 = "chown %s:%s %s" +PKIHELPER_CHOWN_H_3 = "chown -h %s:%s %s" +PKIHELPER_CP_P_2 = "cp -p %s %s" +PKIHELPER_CP_RP_2 = "cp -rp %s %s" +PKIHELPER_DANGLING_SYMLINK_2 = "Dangling symlink '%s'-->'%s'" +PKIHELPER_DIRECTORY_IS_EMPTY_1 = "directory '%s' is empty" +PKIHELPER_DIRECTORY_IS_NOT_EMPTY_1 = "directory '%s' is NOT empty" +PKIHELPER_GID_2 = "GID of '%s' is %s" +PKIHELPER_GROUP_1 = "retrieving GID for '%s' . . ." +PKIHELPER_IS_A_DIRECTORY_1 = "'%s' is a directory" +PKIHELPER_IS_A_FILE_1 = "'%s' is a file" +PKIHELPER_IS_A_SYMLINK_1 = "'%s' is a symlink" +PKIHELPER_JAR_XF_C_2 = "jar -xf %s -C %s" +PKIHELPER_LINK_S_2 = "ln -s %s %s" +PKIHELPER_MKDIR_1 = "mkdir -p %s" +PKIHELPER_MODIFY_DIR_1 = "modifying '%s'" +PKIHELPER_MODIFY_FILE_1 = "modifying '%s'" +PKIHELPER_MODIFY_SYMLINK_1 = "modifying '%s'" +PKIHELPER_PKI_SUBSYSTEM_INSTANCES_2 = "instance '%s' contains '%d' PKI subsystems" +PKIHELPER_RM_F_1 = "rm -f %s" +PKIHELPER_RM_RF_1 = "rm -rf %s" +PKIHELPER_RMDIR_1 = "rmdir %s" +PKIHELPER_SET_MODE_1 = "setting ownerships, permissions, and acls on '%s'" +PKIHELPER_TOMCAT_INSTANCES_2 = "instance '%s' contains '%d' Tomcat PKI subsystems" +PKIHELPER_TOUCH_1 = "touch %s" +PKIHELPER_UID_2 = "UID of '%s' is %s" +PKIHELPER_USER_1 = "retrieving UID for '%s' . . ." + +# PKI Deployment "Scriptlet" Messages +CONFIGURATION_DESTROY_1 = "unconfiguring '%s'" +CONFIGURATION_RESPAWN_1 = "reconfiguring '%s'" +CONFIGURATION_SPAWN_1 = "configuring '%s'" +FINALIZATION_DESTROY_1 = "finalizing '%s'" +FINALIZATION_RESPAWN_1 = "finalizing '%s'" +FINALIZATION_SPAWN_1 = "finalizing '%s'" +INITIALIZATION_DESTROY_1 = "initializing '%s'" +INITIALIZATION_RESPAWN_1 = "initializing '%s'" +INITIALIZATION_SPAWN_1 = "initializing '%s'" +INSTANCE_DESTROY_1 = "depopulating '%s'" +INSTANCE_RESPAWN_1 = "repopulating '%s'" +INSTANCE_SPAWN_1 = "populating '%s'" +RESIDUAL_DESTROY_1 = "depopulating '%s'" +RESIDUAL_RESPAWN_1 = "repopulating '%s'" +RESIDUAL_SPAWN_1 = "populating '%s'" +SECURITY_DATABASES_DESTROY_1 = "removing '%s'" +SECURITY_DATABASES_RESPAWN_1 = "regenerating '%s'" +SECURITY_DATABASES_SPAWN_1 = "generating '%s'" +SLOT_ASSIGNMENT_DESTROY_1 = "unassigning slots for '%s'" +SLOT_ASSIGNMENT_RESPAWN_1 = "reassigning slots for '%s'" +SLOT_ASSIGNMENT_SPAWN_1 = "assigning slots for '%s'" +SUBSYSTEM_DESTROY_1 = "depopulating '%s'" +SUBSYSTEM_RESPAWN_1 = "repopulating '%s'" +SUBSYSTEM_SPAWN_1 = "populating '%s'" +WAR_EXPLOSION_DESTROY_1 = "removing '%s'" +WAR_EXPLOSION_RESPAWN_1 = "redeploying '%s'" +WAR_EXPLOSION_SPAWN_1 = "deploying '%s'" +WEBSERVER_DESTROY_1 = "depopulating '%s'" +WEBSERVER_RESPAWN_1 = "repopulating '%s'" +WEBSERVER_SPAWN_1 = "populating '%s'" diff --git a/base/deploy/src/scriptlets/pkiparser.py b/base/deploy/src/scriptlets/pkiparser.py new file mode 100644 index 000000000..bff405955 --- /dev/null +++ b/base/deploy/src/scriptlets/pkiparser.py @@ -0,0 +1,362 @@ +#!/usr/bin/python -t +# Authors: +# Matthew Harmsen +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; version 2 of the License. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Copyright (C) 2012 Red Hat, Inc. +# All rights reserved. +# + +# System Imports +import ConfigParser +import argparse +import logging +import os + + +# PKI Deployment Imports +import pkiconfig as config +import pkimessages as log + + +# PKI Deployment Helper Functions +def process_command_line_arguments(argv): + "Read and process command-line options" + description = None + if os.path.basename(argv[0]) == 'pkispawn': + description = 'PKI Instance Installation and Configuration' + elif os.path.basename(argv[0]) == 'pkidestroy': + description = 'PKI Instance Removal' + parser = argparse.ArgumentParser( + description=description, + add_help=False, + formatter_class=argparse.RawDescriptionHelpFormatter, + epilog=log.PKI_VERBOSITY) + mandatory = parser.add_argument_group('mandatory arguments') + mandatory.add_argument('-s', + dest='pki_subsystem', action='store', + nargs=1, choices=config.PKI_SUBSYSTEMS, + required=True, metavar='', + help='where is ' + 'CA, KRA, OCSP, RA, TKS, or TPS') + optional = parser.add_argument_group('optional arguments') + optional.add_argument('--dry_run', + dest='pki_dry_run_flag', action='store_true', + help='do not actually perform any actions') + optional.add_argument('-f', + dest='pkideployment_cfg', action='store', + nargs=1, metavar='', + help='overrides default configuration filename') + optional.add_argument('-h', '--help', + dest='help', action='help', + help='show this help message and exit') + optional.add_argument('-p', + dest='pki_root_prefix', action='store', + nargs=1, metavar='', + help='directory prefix to specify local directory') + if os.path.basename(argv[0]) == 'pkispawn': + optional.add_argument('-u', + dest='pki_update_flag', action='store_true', + help='update instance of specified subsystem') + optional.add_argument('-v', + dest='pki_verbosity', action='count', + help='display verbose information (details below)') + custom = parser.add_argument_group('custom arguments ' + '(OVERRIDES configuration file values)') + custom.add_argument('-i', + dest='pki_instance_name', action='store', + nargs=1, metavar='', + help='PKI instance name (MUST specify REQUIRED ports)') + custom.add_argument('--http_port', + dest='pki_http_port', action='store', + nargs=1, metavar='', + help='HTTP port (CA, KRA, OCSP, RA, TKS, TPS)') + custom.add_argument('--https_port', + dest='pki_https_port', action='store', + nargs=1, metavar='', + help='HTTPS port (CA, KRA, OCSP, RA, TKS, TPS)') + custom.add_argument('--ajp_port', + dest='pki_ajp_port', action='store', + nargs=1, metavar='', + help='AJP port (CA, KRA, OCSP, TKS)') + args = parser.parse_args() + + config.pki_subsystem = str(args.pki_subsystem).strip('[\']') + if args.pki_dry_run_flag: + config.pki_dry_run_flag = args.pki_dry_run_flag + if not args.pki_root_prefix is None: + config.pki_root_prefix = str(args.pki_root_prefix).strip('[\']') + if config.pki_root_prefix is None or\ + len(config.pki_root_prefix) == 0: + config.pki_root_prefix = "" + elif not os.path.exists(config.pki_root_prefix) or\ + not os.path.isdir(config.pki_root_prefix): + print "ERROR: " +\ + log.PKI_DIRECTORY_MISSING_OR_NOT_A_DIRECTORY_1 %\ + config.pki_root_prefix + print + parser.print_help() + parser.exit(-1); + if os.path.basename(argv[0]) == 'pkispawn': + if args.pki_update_flag: + config.pki_update_flag = args.pki_update_flag + if args.pki_verbosity == 1: + config.pki_console_log_level = logging.INFO + config.pki_log_level = logging.INFO + elif args.pki_verbosity == 2: + config.pki_console_log_level = logging.INFO + config.pki_log_level = logging.DEBUG + elif args.pki_verbosity == 3: + config.pki_console_log_level = logging.DEBUG + config.pki_log_level = logging.DEBUG + elif args.pki_verbosity > 3: + print "ERROR: " + log.PKI_VERBOSITY_LEVELS_MESSAGE + print + parser.print_help() + parser.exit(-1); + if not args.pki_instance_name is None: + config.pki_instance_name = str(args.pki_instance_name).strip('[\']') + if not args.pki_http_port is None: + config.pki_http_port = str(args.pki_http_port).strip('[\']') + if not args.pki_https_port is None: + config.pki_https_port = str(args.pki_https_port).strip('[\']') + if not args.pki_ajp_port is None: + if config.pki_subsystem in config.PKI_TOMCAT_SUBSYSTEMS: + config.pki_ajp_port = str(args.pki_ajp_port).strip('[\']') + else: + print "ERROR: " +\ + log.PKI_CUSTOM_TOMCAT_AJP_PORT_1 %\ + config.pki_subsystem + print + parser.print_help() + parser.exit(-1); + if not args.pki_instance_name is None or\ + not args.pki_http_port is None or\ + not args.pki_https_port is None or\ + not args.pki_ajp_port is None: + if config.pki_subsystem in config.PKI_APACHE_SUBSYSTEMS: + if args.pki_instance_name is None or\ + args.pki_http_port is None or\ + args.pki_https_port is None: + print "ERROR: " + log.PKI_CUSTOM_APACHE_INSTANCE_1 %\ + config.pki_subsystem + print + parser.print_help() + parser.exit(-1); + elif config.pki_subsystem in config.PKI_TOMCAT_SUBSYSTEMS: + if args.pki_instance_name is None or\ + args.pki_http_port is None or\ + args.pki_https_port is None or\ + args.pki_ajp_port is None: + print "ERROR: " + log.PKI_CUSTOM_TOMCAT_INSTANCE_1 %\ + config.pki_subsystem + print + parser.print_help() + parser.exit(-1); + if not args.pkideployment_cfg is None: + config.pkideployment_cfg = str(args.pkideployment_cfg).strip('[\']') + elif os.path.basename(argv[0]) == 'pkidestroy': + # NOTE: When performing 'pkidestroy', a configuration file must be + # explicitly specified if it does not use the default location + # and/or default configuration file name. + config.pkideployment_cfg = config.pki_root_prefix +\ + config.PKI_DEPLOYMENT_REGISTRY_ROOT + "/" +\ + config.PKI_DEPLOYMENT_DEFAULT_INSTANCE_NAME + "/" +\ + config.pki_subsystem.lower() +"/" +\ + config.PKI_DEPLOYMENT_DEFAULT_CONFIGURATION_FILE + if not os.path.exists(config.pkideployment_cfg) or\ + not os.path.isfile(config.pkideployment_cfg): + print "ERROR: " +\ + log.PKI_FILE_MISSING_OR_NOT_A_FILE_1 %\ + config.pkideployment_cfg + print + parser.print_help() + parser.exit(-1); + return + + +def read_pki_configuration_file(): + "Read configuration file sections into dictionaries" + rv = 0 + try: + parser = ConfigParser.ConfigParser() + parser.read(config.pkideployment_cfg) + config.pki_common_dict = dict(parser._sections['Common']) + if config.pki_subsystem == "CA": + config.pki_web_server_dict = dict(parser._sections['Tomcat']) + config.pki_subsystem_dict = dict(parser._sections['CA']) + elif config.pki_subsystem == "KRA": + config.pki_web_server_dict = dict(parser._sections['Tomcat']) + config.pki_subsystem_dict = dict(parser._sections['KRA']) + elif config.pki_subsystem == "OCSP": + config.pki_web_server_dict = dict(parser._sections['Tomcat']) + config.pki_subsystem_dict = dict(parser._sections['OCSP']) + elif config.pki_subsystem == "RA": + config.pki_web_server_dict = dict(parser._sections['Apache']) + config.pki_subsystem_dict = dict(parser._sections['RA']) + elif config.pki_subsystem == "TKS": + config.pki_web_server_dict = dict(parser._sections['Tomcat']) + config.pki_subsystem_dict = dict(parser._sections['TKS']) + elif config.pki_subsystem == "TPS": + config.pki_web_server_dict = dict(parser._sections['Apache']) + config.pki_subsystem_dict = dict(parser._sections['TPS']) + # Insert empty record into dictionaries for "pretty print" statements + config.pki_common_dict[0] = None + config.pki_web_server_dict[0] = None + config.pki_subsystem_dict[0] = None + except ConfigParser.ParsingError, err: + rv = err + return rv + + +def compose_pki_master_dictionary(): + "Create a single master PKI dictionary from the sectional dictionaries" + config.pki_master_dict = dict() + # 'pkispawn'/'pkirespawn'/'pkidestroy' name/value pairs + config.pki_master_dict['pki_timestamp'] = config.pki_timestamp + # Configuration file name/value pairs + config.pki_master_dict.update(config.pki_common_dict) + config.pki_master_dict.update(config.pki_web_server_dict) + config.pki_master_dict.update(config.pki_subsystem_dict) + config.pki_master_dict.update(__name__="PKI Master Dictionary") + config.pki_master_dict['pki_source_conf'] =\ + config.pki_master_dict['pki_source_root'] + "/" +\ + config.pki_master_dict['pki_subsystem'].lower() + "/" + "conf" + if config.pki_master_dict['pki_subsystem'] in config.PKI_TOMCAT_SUBSYSTEMS: + config.pki_master_dict['pki_war'] =\ + config.pki_master_dict['pki_source_root'] + "/" +\ + config.pki_master_dict['pki_subsystem'].lower() + "/" +\ + "war" + "/" + config.pki_master_dict['pki_war_name'] + config.pki_master_dict['pki_tomcat_bin_path'] =\ + config.pki_master_dict['pki_tomcat_root'] + "/" + "bin" + config.pki_master_dict['pki_tomcat_lib_path'] =\ + config.pki_master_dict['pki_tomcat_root'] + "/" + "lib" + if config.pki_master_dict['pki_subsystem'] == "CA": + config.pki_master_dict['pki_source_emails'] =\ + config.pki_master_dict['pki_source_root'] + "/" +\ + "ca" + "/" + "emails" + config.pki_master_dict['pki_source_profiles'] =\ + config.pki_master_dict['pki_source_root'] + "/" +\ + "ca" + "/" + "profiles" + # Instance layout base name/value pairs + config.pki_master_dict['pki_root_prefix'] = config.pki_root_prefix + config.pki_master_dict['pki_path'] =\ + config.pki_master_dict['pki_root_prefix'] +\ + config.pki_master_dict['pki_instance_root'] + config.pki_master_dict['pki_instance_path'] =\ + config.pki_master_dict['pki_path'] + "/" +\ + config.pki_master_dict['pki_instance_name'] + config.pki_master_dict['pki_instance_database_link'] =\ + config.pki_master_dict['pki_instance_path'] + "/" + "alias" + # Instance layout log name/value pairs + config.pki_master_dict['pki_log_path'] =\ + config.pki_master_dict['pki_root_prefix'] +\ + config.pki_master_dict['pki_instance_log_root'] + config.pki_master_dict['pki_instance_log_path'] =\ + config.pki_master_dict['pki_log_path'] + "/" +\ + config.pki_master_dict['pki_instance_name'] + # Instance layout configuration name/value pairs + config.pki_master_dict['pki_configuration_path'] =\ + config.pki_master_dict['pki_root_prefix'] +\ + config.pki_master_dict['pki_instance_configuration_root'] + config.pki_master_dict['pki_instance_configuration_path'] =\ + config.pki_master_dict['pki_configuration_path'] + "/" +\ + config.pki_master_dict['pki_instance_name'] + # Instance layout registry name/value pairs + config.pki_master_dict['pki_registry_path'] =\ + config.pki_master_dict['pki_root_prefix'] +\ + config.PKI_DEPLOYMENT_REGISTRY_ROOT + config.pki_master_dict['pki_instance_registry_path'] =\ + config.pki_master_dict['pki_registry_path'] + "/" +\ + config.pki_master_dict['pki_instance_name'] + # Instance-based webserver Apache base name/value pairs + if config.pki_master_dict['pki_subsystem'] in config.PKI_APACHE_SUBSYSTEMS: + config.pki_master_dict['pki_apache_path'] =\ + config.pki_master_dict['pki_instance_path'] + "/apache" + # Instance-based webserver Tomcat base name/value pairs + if config.pki_master_dict['pki_subsystem'] in config.PKI_TOMCAT_SUBSYSTEMS: + config.pki_master_dict['pki_tomcat_path'] =\ + config.pki_master_dict['pki_instance_path'] + "/" + "tomcat" + config.pki_master_dict['pki_tomcat_bin_link'] =\ + config.pki_master_dict['pki_tomcat_path'] + "/" + "bin" + config.pki_master_dict['pki_common_path'] =\ + config.pki_master_dict['pki_tomcat_path'] + "/" + "common" + config.pki_master_dict['pki_common_lib_path'] =\ + config.pki_master_dict['pki_common_path'] + "/" + "lib" + config.pki_master_dict['pki_conf_path'] =\ + config.pki_master_dict['pki_tomcat_path'] + "/" + "conf" + config.pki_master_dict['pki_tomcat_lib_link'] =\ + config.pki_master_dict['pki_tomcat_path'] + "/" + "lib" + config.pki_master_dict['pki_tomcat_logs_link'] =\ + config.pki_master_dict['pki_tomcat_path'] + "/" + "logs" + config.pki_master_dict['pki_webapps_path'] =\ + config.pki_master_dict['pki_tomcat_path'] + "/" + "webapps" + config.pki_master_dict['pki_webapps_root_path'] =\ + config.pki_master_dict['pki_webapps_path'] + "/" + "ROOT" + config.pki_master_dict['pki_webapps_root_webinf_path'] =\ + config.pki_master_dict['pki_webapps_root_path'] + "/" + "WEB-INF" + config.pki_master_dict['pki_webapps_webinf_path'] =\ + config.pki_master_dict['pki_webapps_path'] + "/" + "WEB-INF" + config.pki_master_dict['pki_webapps_webinf_classes_path'] =\ + config.pki_master_dict['pki_webapps_webinf_path'] + "/" + "classes" + config.pki_master_dict['pki_webapps_webinf_lib_path'] =\ + config.pki_master_dict['pki_webapps_webinf_path'] + "/" + "lib" + config.pki_master_dict['pki_webapps_subsystem_path'] =\ + config.pki_master_dict['pki_webapps_path'] + "/" +\ + config.pki_master_dict['pki_subsystem'].lower() + config.pki_master_dict['pki_webapps_subsystem_webinf_classes_link'] =\ + config.pki_master_dict['pki_webapps_subsystem_path'] + "/" +\ + "WEB-INF" + "/" + "classes" + config.pki_master_dict['pki_webapps_subsystem_webinf_lib_link'] =\ + config.pki_master_dict['pki_webapps_subsystem_path'] + "/" +\ + "WEB-INF" + "/" + "lib" + # Instance-based webserver Apache/Tomcat configuration name/value pairs + config.pki_master_dict['pki_database_path'] =\ + config.pki_master_dict['pki_instance_configuration_path'] + "/" +\ + "alias" + # Instance-based subsystem base name/value pairs + config.pki_master_dict['pki_subsystem_path'] =\ + config.pki_master_dict['pki_instance_path'] + "/" +\ + config.pki_master_dict['pki_subsystem'].lower() + config.pki_master_dict['pki_subsystem_database_link'] =\ + config.pki_master_dict['pki_subsystem_path'] + "/" + "alias" + config.pki_master_dict['pki_subsystem_configuration_link'] =\ + config.pki_master_dict['pki_subsystem_path'] + "/" + "conf" + config.pki_master_dict['pki_subsystem_logs_link'] =\ + config.pki_master_dict['pki_subsystem_path'] + "/" + "logs" + if config.pki_master_dict['pki_subsystem'] in config.PKI_TOMCAT_SUBSYSTEMS: + if config.pki_master_dict['pki_subsystem'] == "CA": + config.pki_master_dict['pki_subsystem_emails_path'] =\ + config.pki_master_dict['pki_subsystem_path'] + "/" + "emails" + config.pki_master_dict['pki_subsystem_profiles_path'] =\ + config.pki_master_dict['pki_subsystem_path'] + "/" + "profiles" + config.pki_master_dict['pki_subsystem_webapps_link'] =\ + config.pki_master_dict['pki_subsystem_path'] + "/" + "webapps" + # Instance-based subsystem log name/value pairs + config.pki_master_dict['pki_subsystem_log_path'] =\ + config.pki_master_dict['pki_instance_log_path'] + "/" +\ + config.pki_master_dict['pki_subsystem'].lower() + config.pki_master_dict['pki_subsystem_signed_audit_log_path'] =\ + config.pki_master_dict['pki_subsystem_log_path'] + "/" +\ + "signedAudit" + # Instance-based subsystem configuration name/value pairs + config.pki_master_dict['pki_subsystem_configuration_path'] =\ + config.pki_master_dict['pki_instance_configuration_path'] + "/" +\ + config.pki_master_dict['pki_subsystem'].lower() + # Instance-based subsystem registry name/value pairs + config.pki_master_dict['pki_subsystem_registry_path'] =\ + config.pki_master_dict['pki_instance_registry_path'] + "/" +\ + config.pki_master_dict['pki_subsystem'].lower() + return diff --git a/base/deploy/src/scriptlets/pkiscriptlet.py b/base/deploy/src/scriptlets/pkiscriptlet.py index 5befd993a..6f29e2c8b 100644 --- a/base/deploy/src/scriptlets/pkiscriptlet.py +++ b/base/deploy/src/scriptlets/pkiscriptlet.py @@ -15,7 +15,7 @@ # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -# Copyright (C) 2011 Red Hat, Inc. +# Copyright (C) 2012 Red Hat, Inc. # All rights reserved. # @@ -44,4 +44,3 @@ class AbstractBasePkiScriptlet(object): """Retrieve data from the specified PKI dictionary and use it to destroy an existing PKI instance.""" return - diff --git a/base/deploy/src/scriptlets/security_databases.py b/base/deploy/src/scriptlets/security_databases.py index af47cbd5d..093e5ec36 100644 --- a/base/deploy/src/scriptlets/security_databases.py +++ b/base/deploy/src/scriptlets/security_databases.py @@ -15,15 +15,13 @@ # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -# Copyright (C) 2011 Red Hat, Inc. +# Copyright (C) 2012 Red Hat, Inc. # All rights reserved. # -# System Imports -import os - # PKI Deployment Imports import pkiconfig as config +from pkiconfig import pki_master_dict as master import pkimessages as log import pkiscriptlet @@ -31,48 +29,24 @@ import pkiscriptlet # PKI Deployment Security Database Classes class PkiScriptlet(pkiscriptlet.AbstractBasePkiScriptlet): rv = 0 - pki_path = config.pki_root_prefix +\ - config.pki_master_dict['pki_instance_root'] - pki_instance_path = pki_path + "/" +\ - config.pki_master_dict['pki_instance_name'] - pki_subsystem_path = pki_instance_path + "/" +\ - config.pki_master_dict['pki_subsystem'].lower() - pki_database_path = pki_subsystem_path + "/" +\ - config.PKI_SECURITY_DATABASE_DIR def spawn(self): - if not os.path.exists(self.pki_database_path): - config.pki_log.info(log.SECURITY_DATABASES_SPAWN_1, __name__) - elif not os.path.isdir(self.pki_database_path): - config.pki_log.error( - log.PKI_DIRECTORY_ALREADY_EXISTS_NOT_A_DIRECTORY_1, - self.pki_database_path) - self.rv = -1 - else: - config.pki_log.error(log.PKI_DIRECTORY_ALREADY_EXISTS_1, - self.pki_database_path) - self.rv = -1 + config.pki_log.info(log.SECURITY_DATABASES_SPAWN_1, __name__, + extra=config.PKI_INDENTATION_LEVEL_1) + config.pki_log.info("NOT YET IMPLEMENTED", + extra=config.PKI_INDENTATION_LEVEL_2) return self.rv def respawn(self): - if not os.path.exists(self.pki_database_path) or\ - not os.path.isdir(self.pki_database_path): - config.pki_log.error( - log.PKI_DIRECTORY_MISSING_OR_NOT_A_DIRECTORY_1, - self.pki_database_path) - self.rv = -1 - else: - config.pki_log.info(log.SECURITY_DATABASES_RESPAWN_1, __name__) + config.pki_log.info(log.SECURITY_DATABASES_RESPAWN_1, __name__, + extra=config.PKI_INDENTATION_LEVEL_1) + config.pki_log.info("NOT YET IMPLEMENTED", + extra=config.PKI_INDENTATION_LEVEL_2) return self.rv def destroy(self): - if not os.path.exists(self.pki_database_path) or\ - not os.path.isdir(self.pki_database_path): - config.pki_log.error( - log.PKI_DIRECTORY_MISSING_OR_NOT_A_DIRECTORY_1, - self.pki_database_path) - self.rv = -1 - else: - config.pki_log.info(log.SECURITY_DATABASES_DESTROY_1, __name__) + config.pki_log.info(log.SECURITY_DATABASES_DESTROY_1, __name__, + extra=config.PKI_INDENTATION_LEVEL_1) + config.pki_log.info("NOT YET IMPLEMENTED", + extra=config.PKI_INDENTATION_LEVEL_2) return self.rv - diff --git a/base/deploy/src/scriptlets/slot_assignment.py b/base/deploy/src/scriptlets/slot_assignment.py new file mode 100644 index 000000000..6b23ea621 --- /dev/null +++ b/base/deploy/src/scriptlets/slot_assignment.py @@ -0,0 +1,52 @@ +#!/usr/bin/python -t +# Authors: +# Matthew Harmsen +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; version 2 of the License. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Copyright (C) 2012 Red Hat, Inc. +# All rights reserved. +# + +# PKI Deployment Imports +import pkiconfig as config +from pkiconfig import pki_master_dict as master +import pkimessages as log +import pkiscriptlet + + +# PKI Deployment Instance Population Classes +class PkiScriptlet(pkiscriptlet.AbstractBasePkiScriptlet): + rv = 0 + + def spawn(self): + config.pki_log.info(log.SLOT_ASSIGNMENT_SPAWN_1, __name__, + extra=config.PKI_INDENTATION_LEVEL_1) + config.pki_log.info("NOT YET IMPLEMENTED", + extra=config.PKI_INDENTATION_LEVEL_2) + return self.rv + + def respawn(self): + config.pki_log.info(log.SLOT_ASSIGNMENT_RESPAWN_1, __name__, + extra=config.PKI_INDENTATION_LEVEL_1) + config.pki_log.info("NOT YET IMPLEMENTED", + extra=config.PKI_INDENTATION_LEVEL_2) + return self.rv + + def destroy(self): + config.pki_log.info(log.SLOT_ASSIGNMENT_DESTROY_1, __name__, + extra=config.PKI_INDENTATION_LEVEL_1) + config.pki_log.info("NOT YET IMPLEMENTED", + extra=config.PKI_INDENTATION_LEVEL_2) + return self.rv diff --git a/base/deploy/src/scriptlets/subsystem_layout.py b/base/deploy/src/scriptlets/subsystem_layout.py new file mode 100644 index 000000000..b71fe39f0 --- /dev/null +++ b/base/deploy/src/scriptlets/subsystem_layout.py @@ -0,0 +1,107 @@ +#!/usr/bin/python -t +# Authors: +# Matthew Harmsen +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; version 2 of the License. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Copyright (C) 2012 Red Hat, Inc. +# All rights reserved. +# + +# PKI Deployment Imports +import pkiconfig as config +from pkiconfig import pki_master_dict as master +import pkihelper as util +import pkimessages as log +import pkiscriptlet + + +# PKI Deployment Instance Population Classes +class PkiScriptlet(pkiscriptlet.AbstractBasePkiScriptlet): + rv = 0 + + def spawn(self): + config.pki_log.info(log.SUBSYSTEM_SPAWN_1, __name__, + extra=config.PKI_INDENTATION_LEVEL_1) + # establish instance-based subsystem base + util.directory.create(master['pki_subsystem_path']) + if master['pki_subsystem'] == "CA": + util.directory.copy(master['pki_source_emails'], + master['pki_subsystem_emails_path']) + util.directory.copy(master['pki_source_profiles'], + master['pki_subsystem_profiles_path']) + # establish instance-based subsystem logs + util.directory.create(master['pki_subsystem_log_path']) + if master['pki_subsystem'] in config.PKI_SIGNED_AUDIT_SUBSYSTEMS: + util.directory.create(master['pki_subsystem_signed_audit_log_path']) + # establish instance-based subsystem configuration + util.directory.copy(master['pki_source_conf'], + master['pki_subsystem_configuration_path']) + # establish instance-based subsystem registry + util.directory.create(master['pki_subsystem_registry_path']) + # establish convenience symbolic links + util.symlink.create(master['pki_database_path'], + master['pki_subsystem_database_link']) + util.symlink.create(master['pki_subsystem_configuration_path'], + master['pki_subsystem_configuration_link']) + util.symlink.create(master['pki_subsystem_log_path'], + master['pki_subsystem_logs_link']) + util.symlink.create(master['pki_webapps_path'], + master['pki_subsystem_webapps_link']) + return self.rv + + def respawn(self): + config.pki_log.info(log.SUBSYSTEM_RESPAWN_1, __name__, + extra=config.PKI_INDENTATION_LEVEL_1) + # update instance-based subsystem base + util.directory.modify(master['pki_subsystem_path']) + if master['pki_subsystem'] == "CA": + util.directory.copy(master['pki_source_emails'], + master['pki_subsystem_emails_path'], + overwrite_flag=True) + util.directory.copy(master['pki_source_profiles'], + master['pki_subsystem_profiles_path'], + overwrite_flag=True) + # update instance-based subsystem logs + util.directory.modify(master['pki_subsystem_log_path']) + if master['pki_subsystem'] in config.PKI_SIGNED_AUDIT_SUBSYSTEMS: + util.directory.modify(master['pki_subsystem_signed_audit_log_path']) + # update instance-based subsystem configuration + util.directory.copy(master['pki_source_conf'], + master['pki_subsystem_configuration_path'], + overwrite_flag=True) + # update instance-based subsystem registry + util.directory.modify(master['pki_subsystem_registry_path']) + # update convenience symbolic links + util.symlink.modify(master['pki_subsystem_database_link']) + util.symlink.modify(master['pki_subsystem_configuration_link']) + util.symlink.modify(master['pki_subsystem_logs_link']) + util.symlink.modify(master['pki_subsystem_webapps_link']) + return self.rv + + def destroy(self): + config.pki_log.info(log.SUBSYSTEM_DESTROY_1, __name__, + extra=config.PKI_INDENTATION_LEVEL_1) + # remove instance-based subsystem base + if master['pki_subsystem'] == "CA": + util.directory.delete(master['pki_subsystem_profiles_path']) + util.directory.delete(master['pki_subsystem_emails_path']) + util.directory.delete(master['pki_subsystem_path']) + # remove instance-based subsystem logs + util.directory.delete(master['pki_subsystem_log_path']) + # remove instance-based subsystem configuration + util.directory.delete(master['pki_subsystem_configuration_path']) + # remove instance-based subsystem registry + util.directory.delete(master['pki_subsystem_registry_path']) + return self.rv diff --git a/base/deploy/src/scriptlets/war_explosion.py b/base/deploy/src/scriptlets/war_explosion.py new file mode 100644 index 000000000..4f235d8d7 --- /dev/null +++ b/base/deploy/src/scriptlets/war_explosion.py @@ -0,0 +1,69 @@ +#!/usr/bin/python -t +# Authors: +# Matthew Harmsen +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; version 2 of the License. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Copyright (C) 2012 Red Hat, Inc. +# All rights reserved. +# + +# PKI Deployment Imports +import pkiconfig as config +from pkiconfig import pki_master_dict as master +import pkihelper as util +import pkimessages as log +import pkiscriptlet + + +# PKI Deployment Instance Population Classes +class PkiScriptlet(pkiscriptlet.AbstractBasePkiScriptlet): + rv = 0 + + def spawn(self): + if master['pki_subsystem'] in config.PKI_TOMCAT_SUBSYSTEMS: + config.pki_log.info(log.WAR_EXPLOSION_SPAWN_1, __name__, + extra=config.PKI_INDENTATION_LEVEL_1) + # deploy war file + util.directory.create(master['pki_webapps_subsystem_path']) + util.war.explode(master['pki_war'], + master['pki_webapps_subsystem_path']) + # establish convenience symbolic links + util.symlink.create(master['pki_webapps_webinf_classes_path'], + master['pki_webapps_subsystem_webinf_classes_link']) + util.symlink.create(master['pki_webapps_webinf_lib_path'], + master['pki_webapps_subsystem_webinf_lib_link']) + # set ownerships, permissions, and acls + util.directory.set_mode(master['pki_webapps_subsystem_path']) + return self.rv + + def respawn(self): + if master['pki_subsystem'] in config.PKI_TOMCAT_SUBSYSTEMS: + config.pki_log.info(log.WAR_EXPLOSION_RESPAWN_1, __name__, + extra=config.PKI_INDENTATION_LEVEL_1) + # redeploy war file + util.directory.modify(master['pki_webapps_subsystem_path']) + util.war.explode(master['pki_war'], + master['pki_webapps_subsystem_path']) + # update ownerships, permissions, and acls + # NOTE: This includes existing convenience symbolic links + util.directory.set_mode(master['pki_webapps_subsystem_path']) + return self.rv + + def destroy(self): + if master['pki_subsystem'] in config.PKI_TOMCAT_SUBSYSTEMS: + config.pki_log.info(log.WAR_EXPLOSION_DESTROY_1, __name__, + extra=config.PKI_INDENTATION_LEVEL_1) + util.directory.delete(master['pki_webapps_subsystem_path']) + return self.rv diff --git a/base/deploy/src/scriptlets/webserver_layout.py b/base/deploy/src/scriptlets/webserver_layout.py new file mode 100644 index 000000000..9b3deb7b4 --- /dev/null +++ b/base/deploy/src/scriptlets/webserver_layout.py @@ -0,0 +1,119 @@ +#!/usr/bin/python -t +# Authors: +# Matthew Harmsen +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; version 2 of the License. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Copyright (C) 2012 Red Hat, Inc. +# All rights reserved. +# + +# PKI Deployment Imports +import pkiconfig as config +from pkiconfig import pki_master_dict as master +import pkihelper as util +import pkimessages as log +import pkiscriptlet + + +# PKI Deployment Instance Population Classes +class PkiScriptlet(pkiscriptlet.AbstractBasePkiScriptlet): + rv = 0 + + def spawn(self): + config.pki_log.info(log.WEBSERVER_SPAWN_1, __name__, + extra=config.PKI_INDENTATION_LEVEL_1) + # establish instance-based webserver base + if master['pki_subsystem'] in config.PKI_APACHE_SUBSYSTEMS: + util.directory.create(master['pki_apache_path']) + elif master['pki_subsystem'] in config.PKI_TOMCAT_SUBSYSTEMS: + util.directory.create(master['pki_tomcat_path']) + util.directory.create(master['pki_common_path']) + util.directory.create(master['pki_common_lib_path']) + util.directory.create(master['pki_conf_path']) + util.directory.create(master['pki_webapps_path']) + util.directory.create(master['pki_webapps_root_path']) + util.directory.create(master['pki_webapps_root_webinf_path']) + util.directory.create(master['pki_webapps_webinf_path']) + util.directory.create(master['pki_webapps_webinf_classes_path']) + util.directory.create(master['pki_webapps_webinf_lib_path']) + # establish instance-based webserver configuration + util.directory.create(master['pki_database_path']) + # establish convenience symbolic links + util.symlink.create(master['pki_database_path'], + master['pki_instance_database_link']) + util.symlink.create(master['pki_tomcat_bin_path'], + master['pki_tomcat_bin_link']) + util.symlink.create(master['pki_tomcat_lib_path'], + master['pki_tomcat_lib_link']) + util.symlink.create(master['pki_instance_log_path'], + master['pki_tomcat_logs_link']) + return self.rv + + def respawn(self): + config.pki_log.info(log.WEBSERVER_RESPAWN_1, __name__, + extra=config.PKI_INDENTATION_LEVEL_1) + # update instance-based webserver base + if master['pki_subsystem'] in config.PKI_APACHE_SUBSYSTEMS: + util.directory.modify(master['pki_apache_path']) + elif master['pki_subsystem'] in config.PKI_TOMCAT_SUBSYSTEMS: + util.directory.modify(master['pki_tomcat_path']) + util.directory.modify(master['pki_common_path']) + util.directory.modify(master['pki_common_lib_path']) + util.directory.modify(master['pki_conf_path']) + util.directory.modify(master['pki_webapps_path']) + util.directory.modify(master['pki_webapps_root_path']) + util.directory.modify(master['pki_webapps_root_webinf_path']) + util.directory.modify(master['pki_webapps_webinf_path']) + util.directory.modify(master['pki_webapps_webinf_classes_path']) + util.directory.modify(master['pki_webapps_webinf_lib_path']) + # update instance-based webserver configuration + util.directory.modify(master['pki_database_path']) + # update convenience symbolic links + util.symlink.modify(master['pki_instance_database_link']) + util.symlink.modify(master['pki_tomcat_bin_link']) + util.symlink.modify(master['pki_tomcat_lib_link']) + util.symlink.modify(master['pki_tomcat_logs_link']) + return self.rv + + def destroy(self): + config.pki_log.info(log.WEBSERVER_DESTROY_1, __name__, + extra=config.PKI_INDENTATION_LEVEL_1) + # remove instance-based webserver base + if not config.pki_dry_run_flag and\ + master['pki_subsystem'] in config.PKI_APACHE_SUBSYSTEMS and\ + util.instance.apache_instances(master['pki_instance_path']) == 0: + util.directory.delete(master['pki_apache_path']) + elif master['pki_subsystem'] in config.PKI_APACHE_SUBSYSTEMS and\ + util.instance.apache_instances(master['pki_instance_path']) == 1: + # always display correct information (even during dry_run) + util.directory.delete(master['pki_apache_path']) + if not config.pki_dry_run_flag and\ + master['pki_subsystem'] in config.PKI_TOMCAT_SUBSYSTEMS and\ + util.instance.tomcat_instances(master['pki_instance_path']) == 0: + util.directory.delete(master['pki_tomcat_path']) + elif master['pki_subsystem'] in config.PKI_TOMCAT_SUBSYSTEMS and\ + util.instance.tomcat_instances(master['pki_instance_path']) == 1: + # always display correct information (even during dry_run) + util.directory.delete(master['pki_tomcat_path']) + # remove instance-based webserver configuration + if not config.pki_dry_run_flag and\ + util.instance.pki_subsystem_instances(\ + master['pki_instance_path']) == 0: + util.directory.delete(master['pki_database_path']) + elif util.instance.pki_subsystem_instances(\ + master['pki_instance_path']) == 1: + # always display correct information (even during dry_run) + util.directory.delete(master['pki_database_path']) + return self.rv -- cgit