Log script options to logfile

Uses a new subclass IPAOptionParser in scripts instead of OptionParser
from the standard python library. IPAOptionParser uses its own IPAOption
class to store options, which adds a new 'sensitive' attribute.

https://fedorahosted.org/freeipa/ticket/393
This commit is contained in:
Jakub Hrozek 2010-10-29 20:24:31 +02:00 committed by Rob Crittenden
parent 2205620664
commit 594adb9877
6 changed files with 83 additions and 29 deletions

View File

@ -19,7 +19,6 @@
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
# #
from optparse import OptionParser
import traceback import traceback
from ipaserver.plugins.ldap2 import ldap2 from ipaserver.plugins.ldap2 import ldap2
@ -28,11 +27,12 @@ from ipaserver.install.installutils import *
from ipapython import version from ipapython import version
from ipapython import ipautil, sysrestore from ipapython import ipautil, sysrestore
from ipalib import api, errors, util from ipalib import api, errors, util
from ipapython.config import IPAOptionParser
def parse_options(): def parse_options():
parser = OptionParser(version=version.VERSION) parser = IPAOptionParser(version=version.VERSION)
parser.add_option("-p", "--ds-password", dest="dm_password", parser.add_option("-p", "--ds-password", dest="dm_password",
help="admin password") sensitive=True, help="admin password")
parser.add_option("-d", "--debug", dest="debug", action="store_true", parser.add_option("-d", "--debug", dest="debug", action="store_true",
default=False, help="print debugging information") default=False, help="print debugging information")
parser.add_option("--ip-address", dest="ip_address", help="Master Server IP Address") parser.add_option("--ip-address", dest="ip_address", help="Master Server IP Address")
@ -46,6 +46,7 @@ def parse_options():
default=False, help="unattended installation never prompts the user") default=False, help="unattended installation never prompts the user")
options, args = parser.parse_args() options, args = parser.parse_args()
safe_options = parser.get_safe_opts(options)
if options.forwarders and options.no_forwarders: if options.forwarders and options.no_forwarders:
parser.error("You cannot specify a --forwarder option together with --no-forwarders") parser.error("You cannot specify a --forwarder option together with --no-forwarders")
@ -56,7 +57,7 @@ def parse_options():
if not options.forwarders and not options.no_forwarders: if not options.forwarders and not options.no_forwarders:
parser.error("You must specify at least one --forwarder option or --no-forwarders option") parser.error("You must specify at least one --forwarder option or --no-forwarders option")
return options return safe_options, options
def resolve_host(host_name): def resolve_host(host_name):
ip = None ip = None
@ -76,7 +77,7 @@ def resolve_host(host_name):
return ip return ip
def main(): def main():
options = parse_options() safe_options, options = parse_options()
if os.getegid() != 0: if os.getegid() != 0:
print "Must be root to setup server" print "Must be root to setup server"
@ -85,6 +86,8 @@ def main():
standard_logging_setup("/var/log/ipaserver-install.log", options.debug, filemode='a') standard_logging_setup("/var/log/ipaserver-install.log", options.debug, filemode='a')
print "\nThe log file for this installation can be found in /var/log/ipaserver-install.log" print "\nThe log file for this installation can be found in /var/log/ipaserver-install.log"
logging.debug('%s was invoked with options: %s' % (sys.argv[0], safe_options))
global fstore global fstore
fstore = sysrestore.FileStore('/var/lib/ipa/sysrestore') fstore = sysrestore.FileStore('/var/lib/ipa/sysrestore')

View File

@ -25,7 +25,7 @@
import sys import sys
try: try:
from optparse import OptionParser from ipapython.config import IPAOptionParser
from ipapython import ipautil, config from ipapython import ipautil, config
from ipaserver.install import installutils from ipaserver.install import installutils
from ipaserver.install.ldapupdate import LDAPUpdate, BadSyntax, UPDATES_DIR from ipaserver.install.ldapupdate import LDAPUpdate, BadSyntax, UPDATES_DIR
@ -44,7 +44,7 @@ error was:
def parse_options(): def parse_options():
usage = "%prog [options] input_file(s)\n" usage = "%prog [options] input_file(s)\n"
usage += "%prog [options]\n" usage += "%prog [options]\n"
parser = OptionParser(usage=usage, formatter=config.IPAFormatter()) parser = IPAOptionParser(usage=usage, formatter=config.IPAFormatter())
parser.add_option("-d", "--debug", action="store_true", dest="debug", parser.add_option("-d", "--debug", action="store_true", dest="debug",
help="Display debugging information about the update(s)") help="Display debugging information about the update(s)")
@ -59,10 +59,11 @@ def parse_options():
config.add_standard_options(parser) config.add_standard_options(parser)
options, args = parser.parse_args() options, args = parser.parse_args()
safe_options = parser.get_safe_opts(options)
config.init_config(options) config.init_config(options)
return options, args return safe_options, options, args
def get_dirman_password(): def get_dirman_password():
"""Prompt the user for the Directory Manager password and verify its """Prompt the user for the Directory Manager password and verify its
@ -75,7 +76,7 @@ def get_dirman_password():
def main(): def main():
loglevel = logging.INFO loglevel = logging.INFO
options, args = parse_options() safe_options, options, args = parse_options()
if options.debug: if options.debug:
loglevel = logging.DEBUG loglevel = logging.DEBUG
@ -95,6 +96,7 @@ def main():
logging.basicConfig(level=loglevel, logging.basicConfig(level=loglevel,
format='%(levelname)s %(message)s', format='%(levelname)s %(message)s',
filename='/var/log/ipaupgrade.log') filename='/var/log/ipaupgrade.log')
logging.debug('%s was invoked with arguments %s and options: %s' % (sys.argv[0], args, safe_options))
realm = krbV.default_context().default_realm realm = krbV.default_context().default_realm
upgrade = IPAUpgrade(realm, files, live_run=not options.test) upgrade = IPAUpgrade(realm, files, live_run=not options.test)
upgrade.create_instance() upgrade.create_instance()

View File

@ -31,6 +31,7 @@ from ipaserver.install import bindinstance, httpinstance, ntpinstance, certs
from ipaserver.plugins.ldap2 import ldap2 from ipaserver.plugins.ldap2 import ldap2
from ipapython import version from ipapython import version
from ipalib import api, errors, util from ipalib import api, errors, util
from ipapython.config import IPAOptionParser
CACERT="/usr/share/ipa/html/ca.crt" CACERT="/usr/share/ipa/html/ca.crt"
@ -50,14 +51,13 @@ class ReplicaConfig:
self.subject_base = "O=IPA" self.subject_base = "O=IPA"
def parse_options(): def parse_options():
from optparse import OptionParser
usage = "%prog [options] REPLICA_FILE" usage = "%prog [options] REPLICA_FILE"
parser = OptionParser(usage=usage, version=version.VERSION) parser = IPAOptionParser(usage=usage, version=version.VERSION)
parser.add_option("-N", "--no-ntp", dest="conf_ntp", action="store_false", parser.add_option("-N", "--no-ntp", dest="conf_ntp", action="store_false",
help="do not configure ntp", default=True) help="do not configure ntp", default=True)
parser.add_option("-d", "--debug", dest="debug", action="store_true", parser.add_option("-d", "--debug", dest="debug", action="store_true",
default=False, help="gather extra debugging information") default=False, help="gather extra debugging information")
parser.add_option("-p", "--password", dest="password", parser.add_option("-p", "--password", dest="password", sensitive=True,
help="Directory Manager (existing master) password") help="Directory Manager (existing master) password")
parser.add_option("--setup-dns", dest="setup_dns", action="store_true", parser.add_option("--setup-dns", dest="setup_dns", action="store_true",
default=False, help="configure bind with our zone") default=False, help="configure bind with our zone")
@ -70,6 +70,7 @@ def parse_options():
help="Do not use DNS for hostname lookup during installation") help="Do not use DNS for hostname lookup during installation")
options, args = parser.parse_args() options, args = parser.parse_args()
safe_options = parser.get_safe_opts(options)
if len(args) != 1: if len(args) != 1:
parser.error("you must provide a file generated by ipa-replica-prepare") parser.error("you must provide a file generated by ipa-replica-prepare")
@ -84,7 +85,7 @@ def parse_options():
elif not options.forwarders and not options.no_forwarders: elif not options.forwarders and not options.no_forwarders:
parser.error("You must specify at least one --forwarder option or --no-forwarders option") parser.error("You must specify at least one --forwarder option or --no-forwarders option")
return options, args[0] return safe_options, options, args[0]
def get_dirman_password(): def get_dirman_password():
return installutils.read_password("Directory Manager (existing master)", confirm=False, validate=False) return installutils.read_password("Directory Manager (existing master)", confirm=False, validate=False)
@ -261,8 +262,9 @@ def check_bind():
sys.exit(1) sys.exit(1)
def main(): def main():
options, filename = parse_options() safe_options, options, filename = parse_options()
installutils.standard_logging_setup("/var/log/ipareplica-install.log", options.debug) installutils.standard_logging_setup("/var/log/ipareplica-install.log", options.debug)
logging.debug('%s was invoked with argument "%s" and options: %s' % (sys.argv[0], filename, safe_options))
if not ipautil.file_exists(filename): if not ipautil.file_exists(filename):
sys.exit("Replica file %s does not exist" % filename) sys.exit("Replica file %s does not exist" % filename)

View File

@ -35,7 +35,6 @@ import signal
import shutil import shutil
import glob import glob
import traceback import traceback
from optparse import OptionParser
from ConfigParser import RawConfigParser from ConfigParser import RawConfigParser
import random import random
@ -55,6 +54,7 @@ from ipaserver.plugins.ldap2 import ldap2
from ipapython import sysrestore from ipapython import sysrestore
from ipapython.ipautil import * from ipapython.ipautil import *
from ipalib import api, errors, util from ipalib import api, errors, util
from ipapython.config import IPAOptionParser
pw_name = None pw_name = None
@ -65,7 +65,7 @@ MAXINT_32BIT = 2147483648
def parse_options(): def parse_options():
namespace = random.randint(1000000, (MAXINT_32BIT - 1000000)) namespace = random.randint(1000000, (MAXINT_32BIT - 1000000))
parser = OptionParser(version=version.VERSION) parser = IPAOptionParser(version=version.VERSION)
parser.add_option("-u", "--user", dest="ds_user", parser.add_option("-u", "--user", dest="ds_user",
help="ds user") help="ds user")
parser.add_option("-r", "--realm", dest="realm_name", parser.add_option("-r", "--realm", dest="realm_name",
@ -73,10 +73,12 @@ def parse_options():
parser.add_option("-n", "--domain", dest="domain_name", parser.add_option("-n", "--domain", dest="domain_name",
help="domain name") help="domain name")
parser.add_option("-p", "--ds-password", dest="dm_password", parser.add_option("-p", "--ds-password", dest="dm_password",
help="admin password") sensitive=True, help="admin password")
parser.add_option("-P", "--master-password", dest="master_password", parser.add_option("-P", "--master-password",
dest="master_password", sensitive=True,
help="kerberos master password (normally autogenerated)") help="kerberos master password (normally autogenerated)")
parser.add_option("-a", "--admin-password", dest="admin_password", parser.add_option("-a", "--admin-password",
sensitive=True, dest="admin_password",
help="admin user kerberos password") help="admin user kerberos password")
parser.add_option("-d", "--debug", dest="debug", action="store_true", parser.add_option("-d", "--debug", dest="debug", action="store_true",
default=False, help="print debugging information") default=False, help="print debugging information")
@ -108,9 +110,9 @@ def parse_options():
help="PKCS#12 file containing the Directory Server SSL certificate") help="PKCS#12 file containing the Directory Server SSL certificate")
parser.add_option("--http_pkcs12", dest="http_pkcs12", parser.add_option("--http_pkcs12", dest="http_pkcs12",
help="PKCS#12 file containing the Apache Server SSL certificate") help="PKCS#12 file containing the Apache Server SSL certificate")
parser.add_option("--dirsrv_pin", dest="dirsrv_pin", parser.add_option("--dirsrv_pin", dest="dirsrv_pin", sensitive=True,
help="The password of the Directory Server PKCS#12 file") help="The password of the Directory Server PKCS#12 file")
parser.add_option("--http_pin", dest="http_pin", parser.add_option("--http_pin", dest="http_pin", sensitive=True,
help="The password of the Apache Server PKCS#12 file") help="The password of the Apache Server PKCS#12 file")
parser.add_option("--no-host-dns", dest="no_host_dns", action="store_true", parser.add_option("--no-host-dns", dest="no_host_dns", action="store_true",
default=False, default=False,
@ -126,6 +128,7 @@ def parse_options():
action="store_true", action="store_true",
help="Don't install allow_all HBAC rule") help="Don't install allow_all HBAC rule")
options, args = parser.parse_args() options, args = parser.parse_args()
safe_options = parser.get_safe_opts(options)
if not options.setup_dns: if not options.setup_dns:
if options.forwarders: if options.forwarders:
@ -167,7 +170,7 @@ def parse_options():
if (options.external_cert_file and not os.path.isabs(options.external_cert_file)): if (options.external_cert_file and not os.path.isabs(options.external_cert_file)):
parser.error("--external-cert-file must use an absolute path") parser.error("--external-cert-file must use an absolute path")
return options return safe_options, options
def signal_handler(signum, frame): def signal_handler(signum, frame):
global ds global ds
@ -432,7 +435,7 @@ def main():
global uninstalling global uninstalling
ds = None ds = None
options = parse_options() safe_options, options = parse_options()
if os.getegid() != 0: if os.getegid() != 0:
print "Must be root to set up server" print "Must be root to set up server"
@ -450,6 +453,8 @@ def main():
if dsinstance.DsInstance().is_configured() or cainstance.CADSInstance().is_configured(): if dsinstance.DsInstance().is_configured() or cainstance.CADSInstance().is_configured():
sys.exit("IPA server is already configured on this system.") sys.exit("IPA server is already configured on this system.")
logging.debug('%s was invoked with options: %s' % (sys.argv[0], safe_options))
global fstore global fstore
fstore = sysrestore.FileStore('/var/lib/ipa/sysrestore') fstore = sysrestore.FileStore('/var/lib/ipa/sysrestore')

View File

@ -28,7 +28,6 @@ try:
import logging import logging
import tempfile import tempfile
import getpass import getpass
from optparse import OptionParser
import ipaclient.ipadiscovery import ipaclient.ipadiscovery
import ipaclient.ipachangeconf import ipaclient.ipachangeconf
import ipaclient.ntpconf import ipaclient.ntpconf
@ -36,6 +35,7 @@ try:
from ipapython import sysrestore from ipapython import sysrestore
from ipapython import version from ipapython import version
from ipapython import certmonger from ipapython import certmonger
from ipapython.config import IPAOptionParser
import SSSDConfig import SSSDConfig
from ConfigParser import RawConfigParser from ConfigParser import RawConfigParser
except ImportError: except ImportError:
@ -50,7 +50,7 @@ error was:
client_nss_nickname = 'IPA Machine Certificate - %s' % socket.getfqdn() client_nss_nickname = 'IPA Machine Certificate - %s' % socket.getfqdn()
def parse_options(): def parse_options():
parser = OptionParser(version=version.VERSION) parser = IPAOptionParser(version=version.VERSION)
parser.add_option("--domain", dest="domain", help="domain name") parser.add_option("--domain", dest="domain", help="domain name")
parser.add_option("--server", dest="server", help="IPA server") parser.add_option("--server", dest="server", help="IPA server")
parser.add_option("--realm", dest="realm_name", help="realm name") parser.add_option("--realm", dest="realm_name", help="realm name")
@ -66,7 +66,7 @@ def parse_options():
help="do not configure sssd", default=True, dest="sssd") help="do not configure sssd", default=True, dest="sssd")
parser.add_option("-N", "--no-ntp", action="store_false", parser.add_option("-N", "--no-ntp", action="store_false",
help="do not configure ntp", default=True, dest="conf_ntp") help="do not configure ntp", default=True, dest="conf_ntp")
parser.add_option("-w", "--password", dest="password", parser.add_option("-w", "--password", dest="password", sensitive=True,
help="password to join the IPA realm (assumes bulk password unless principal is also set)"), help="password to join the IPA realm (assumes bulk password unless principal is also set)"),
parser.add_option("-W", dest="prompt_password", action="store_true", parser.add_option("-W", dest="prompt_password", action="store_true",
default=False, default=False,
@ -83,11 +83,12 @@ def parse_options():
default=False, help="uninstall an existing installation") default=False, help="uninstall an existing installation")
options, args = parser.parse_args() options, args = parser.parse_args()
safe_opts = parser.get_safe_opts(options)
if (options.server and not options.domain): if (options.server and not options.domain):
parser.error("--server cannot be used without providing --domain") parser.error("--server cannot be used without providing --domain")
return options return safe_opts, options
def logging_setup(options): def logging_setup(options):
# Always log everything (i.e., DEBUG) to the log # Always log everything (i.e., DEBUG) to the log
@ -500,8 +501,9 @@ def configure_sssd_conf(fstore, cli_domain, cli_server, options):
return 0 return 0
def main(): def main():
options = parse_options() safe_options, options = parse_options()
logging_setup(options) logging_setup(options)
logging.debug('%s was invoked with options: %s' % (sys.argv[0], safe_options))
dnsok = False dnsok = False
env={"PATH":"/bin:/sbin:/usr/kerberos/bin:/usr/kerberos/sbin:/usr/bin:/usr/sbin"} env={"PATH":"/bin:/sbin:/usr/kerberos/bin:/usr/kerberos/sbin:/usr/bin:/usr/sbin"}

View File

@ -18,7 +18,7 @@
# #
import ConfigParser import ConfigParser
from optparse import OptionParser, IndentedHelpFormatter from optparse import Option, Values, OptionParser, IndentedHelpFormatter
import socket import socket
import ipapython.dnsclient import ipapython.dnsclient
@ -46,6 +46,46 @@ class IPAFormatter(IndentedHelpFormatter):
ret += "%s %s\n" % (spacing, line) ret += "%s %s\n" % (spacing, line)
return ret return ret
class IPAOption(Option):
"""
optparse.Option subclass with support of options labeled as
security-sensitive such as passwords.
"""
ATTRS = Option.ATTRS + ["sensitive"]
class IPAOptionParser(OptionParser):
"""
optparse.OptionParser subclass that uses IPAOption by default
for storing options.
"""
def __init__(self,
usage=None,
option_list=None,
option_class=IPAOption,
version=None,
conflict_handler="error",
description=None,
formatter=None,
add_help_option=True,
prog=None):
OptionParser.__init__(self, usage, option_list, option_class,
version, conflict_handler, description,
formatter, add_help_option, prog)
def get_safe_opts(self, opts):
"""
Returns all options except those with sensitive=True in the same
fashion as parse_args would
"""
all_opts_dict = dict([ (o.dest, o) for o in self._get_all_options() if hasattr(o, 'sensitive') ])
safe_opts_dict = {}
for option, value in opts.__dict__.iteritems():
if all_opts_dict[option].sensitive != True:
safe_opts_dict[option] = value
return Values(safe_opts_dict)
def verify_args(parser, args, needed_args = None): def verify_args(parser, args, needed_args = None):
"""Verify that we have all positional arguments we need, if not, exit.""" """Verify that we have all positional arguments we need, if not, exit."""
if needed_args: if needed_args: