freeipa/install/tools/ipactl

321 lines
9.9 KiB
Plaintext
Raw Normal View History

#!/usr/bin/python
# Authors: Simo Sorce <ssorce@redhat.com>
#
# Copyright (C) 2008-2010 Red Hat
# see file 'COPYING' for use and warranty information
#
# 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, either version 3 of the License, or
# (at your option) any later version.
#
# 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, see <http://www.gnu.org/licenses/>.
#
import sys
try:
import os
from ipaserver.install import service
from ipapython import sysrestore
from ipapython import config
from ipalib import api, errors
import logging
import ldap
import ldap.sasl
import socket
except ImportError:
print >> sys.stderr, """\
There was a problem importing one of the required Python modules. The
error was:
%s
""" % sys.exc_value
sys.exit(1)
SASL_EXTERNAL = ldap.sasl.sasl({}, 'EXTERNAL')
class IpactlError(StandardError):
def __init__(self, msg = '', rval = 1):
self.msg = msg
self.rval = rval
def __str__(self):
return self.msg
def check_IPA_configuration():
if not sysrestore.FileStore('/var/lib/ipa/sysrestore').has_files():
# LSB status code 6: program is not configured
raise IpactlError("IPA is not configured " +
"(see man pages of ipa-server-install for help)", 6)
def parse_options():
usage = "%prog start|stop|restart|status\n"
parser = config.IPAOptionParser(usage=usage,
formatter=config.IPAFormatter())
parser.add_option("-d", "--debug", action="store_true", dest="debug",
help="Display debugging information")
options, args = parser.parse_args()
safe_options = parser.get_safe_opts(options)
return safe_options, options, args
def emit_err(err):
sys.stderr.write(err + '\n')
def get_config():
base = "cn=%s,cn=masters,cn=ipa,cn=etc,%s" % (api.env.host,
api.env.basedn)
srcfilter = '(ipaConfigString=enabledService)'
attrs = ['cn', 'ipaConfigString']
try:
con = ldap.initialize(api.env.ldap_uri)
con.sasl_interactive_bind_s('', SASL_EXTERNAL)
res = con.search_st(base,
ldap.SCOPE_SUBTREE,
filterstr=srcfilter,
attrlist=attrs,
timeout=10)
except ldap.SERVER_DOWN, e:
# LSB status code 3: program is not running
raise IpactlError("Failed to get list of services to probe status:\n" +
"Directory Server is stopped", 3)
except Exception, e:
raise IpactlError("Unknown error when retrieving list of services from LDAP: " + str(e))
svc_list = []
for entry in res:
name = entry[1]['cn'][0]
for p in entry[1]['ipaConfigString']:
if p.startswith('startOrder '):
order = p.split()[1]
svc_list.append((order, name))
return svc_list
def ipa_start():
try:
print "Starting Directory Service"
service.start('dirsrv', capture_output=False)
except Exception, e:
raise IpactlError("Failed to start Directory Service: " + str(e))
svc_list = []
try:
svc_list = get_config()
except Exception, e:
emit_err("Failed to read data from Directory Service: " + str(e))
emit_err("Shutting down")
try:
service.stop('dirsrv', capture_output=False)
except:
pass
if isinstance(e, IpactlError):
# do not display any other error message
raise IpactlError(None, e.rval)
else:
raise IpactlError(None)
if len(svc_list) == 0:
# no service to stop
return
for (order, svc) in sorted(svc_list):
svc_name = service.SERVICE_LIST[svc][0]
try:
print "Starting %s Service" % svc
service.start(svc_name, capture_output=False)
except:
emit_err("Failed to start %s Service" % svc)
emit_err("Shutting down")
for (order, svc) in sorted(svc_list):
svc_name = service.SERVICE_LIST[svc][0]
try:
service.stop(svc_name, capture_output=False)
except:
pass
try:
service.stop('dirsrv', capture_output=False)
except:
pass
raise IpactlError("Aborting ipactl")
def ipa_stop():
svc_list = []
try:
svc_list = get_config()
except Exception, e:
# ok if dirsrv died this may fail, so let's try to quickly restart it
# and see if we can get anything. If not throw our hands up and just
# exit
try:
service.start('dirsrv', capture_output=False)
svc_list = get_config()
except Exception, e:
emit_err("Failed to read data from Directory Service: " + str(e))
emit_err("Shutting down")
try:
# just try to stop it, do not read a result
service.stop('dirsrv')
finally:
raise IpactlError(None)
if len(svc_list) == 0:
# no service to stop
return
for (order, svc) in sorted(svc_list, reverse=True):
svc_name = service.SERVICE_LIST[svc][0]
try:
print "Stopping %s Service" % svc
service.stop(svc_name, capture_output=False)
except:
emit_err("Failed to stop %s Service" % svc)
try:
print "Stopping Directory Service"
service.stop('dirsrv', capture_output=False)
except:
raise IpactlError("Failed to stop Directory Service")
def ipa_restart():
try:
print "Restarting Directory Service"
service.restart('dirsrv', capture_output=False)
except Exception, e:
raise IpactlError("Failed to restart Directory Service: " + str(e))
svc_list = []
try:
svc_list = get_config()
except Exception, e:
emit_err("Failed to read data from Directory Service: " + str(e))
emit_err("Shutting down")
try:
service.stop('dirsrv', capture_output=False)
except:
pass
if isinstance(e, IpactlError):
# do not display any other error message
raise IpactlError(None, e.rval)
else:
raise IpactlError(None)
if len(svc_list) == 0:
# no service to stop
return
for (order, svc) in sorted(svc_list):
svc_name = service.SERVICE_LIST[svc][0]
try:
print "Restarting %s Service" % svc
service.restart(svc_name, capture_output=False)
except:
emit_err("Failed to restart %s Service" % svc)
emit_err("Shutting down")
for (order, svc) in sorted(svc_list):
svc_name = service.SERVICE_LIST[svc][0]
try:
service.stop(svc_name, capture_output=False)
except:
pass
try:
service.stop('dirsrv', capture_output=False)
except:
pass
raise IpactlError("Aborting ipactl")
def ipa_status():
try:
if service.is_running('dirsrv'):
print "Directory Service: RUNNING"
else:
print "Directory Service: STOPPED"
except:
raise IpactlError("Failed to get Directory Service status")
svc_list = []
try:
svc_list = get_config()
except IpactlError, e:
raise e
except Exception, e:
raise IpactlError("Failed to get list of services to probe status: " + str(e))
if len(svc_list) == 0:
return
for (order, svc) in sorted(svc_list):
svc_name = service.SERVICE_LIST[svc][0]
try:
if service.is_running(svc_name):
print "%s Service: RUNNING" % svc
else:
print "%s Service: STOPPED" % svc
except:
emit_err("Failed to get %s Service status" % svc)
def main():
if not os.getegid() == 0:
# LSB status code 4: user had insufficient privilege
raise IpactlError("You must be root to run ipactl.", 4)
safe_options, options, args = parse_options()
if len(args) != 1:
# LSB status code 2: invalid or excess argument(s)
raise IpactlError("You must specify one action", 2)
elif args[0] != "start" and args[0] != "stop" and args[0] != "restart" and args[0] != "status":
raise IpactlError("Unrecognized action [" + args[0] + "]", 2)
# check if IPA is configured at all
try:
check_IPA_configuration()
except IpactlError, e:
if args[0].lower() == "status":
# Different LSB return code for status command:
# 4 - program or service status is unknown
# This should differentiate uninstalled IPA from status
# code 3 - program is not running
e.rval = 4
raise e
else:
raise e
api.bootstrap(context='cli', debug=options.debug)
api.finalize()
if args[0].lower() == "start":
ipa_start()
elif args[0].lower() == "stop":
ipa_stop()
elif args[0].lower() == "restart":
ipa_restart()
elif args[0].lower() == "status":
ipa_status()
try:
if __name__ == "__main__":
sys.exit(main())
except IpactlError, e:
if e.msg:
emit_err(e.msg)
sys.exit(e.rval)
except RuntimeError, e:
emit_err("%s" % e)
sys.exit(1)
except SystemExit, e:
sys.exit(e)
except KeyboardInterrupt, e:
sys.exit(1)