summaryrefslogtreecommitdiffstats
path: root/src/sbin
diff options
context:
space:
mode:
Diffstat (limited to 'src/sbin')
-rwxr-xr-xsrc/sbin/bcfg222
-rwxr-xr-xsrc/sbin/bcfg2-info19
-rwxr-xr-xsrc/sbin/bcfg2-lint23
-rwxr-xr-xsrc/sbin/bcfg2-reports145
-rwxr-xr-xsrc/sbin/bcfg2-server2
5 files changed, 162 insertions, 49 deletions
diff --git a/src/sbin/bcfg2 b/src/sbin/bcfg2
index 7f7d8f5c6..5ddfd8791 100755
--- a/src/sbin/bcfg2
+++ b/src/sbin/bcfg2
@@ -7,6 +7,7 @@ import fcntl
import logging
import os
import signal
+import socket
import stat
import sys
import tempfile
@@ -75,6 +76,7 @@ class Client:
'certificate': Bcfg2.Options.CLIENT_CERT,
'ca': Bcfg2.Options.CLIENT_CA,
'serverCN': Bcfg2.Options.CLIENT_SCNS,
+ 'timeout': Bcfg2.Options.CLIENT_TIMEOUT,
}
self.setup = Bcfg2.Options.OptionParser(optinfo)
@@ -178,10 +180,11 @@ class Client:
proxy = Bcfg2.Proxy.ComponentProxy(self.setup['server'],
self.setup['user'],
self.setup['password'],
- key = self.setup['key'],
- cert = self.setup['certificate'],
- ca = self.setup['ca'],
- allowedServerCNs = self.setup['serverCN'])
+ key=self.setup['key'],
+ cert=self.setup['certificate'],
+ ca=self.setup['ca'],
+ allowedServerCNs=self.setup['serverCN'],
+ timeout=self.setup['timeout'])
if self.setup['profile']:
try:
@@ -197,6 +200,13 @@ class Client:
self.logger.error("Failed to download probes from bcfg2")
self.logger.error(flt.faultString)
raise SystemExit(1)
+ except (Bcfg2.Proxy.CertificateError,
+ socket.gaierror,
+ socket.error):
+ e = sys.exc_info()[1]
+ self.logger.error("Failed to download probes from bcfg2: %s"
+ % e)
+ raise SystemExit(1)
times['probe_download'] = time.time()
@@ -243,7 +253,7 @@ class Client:
raise SystemExit(1)
try:
- rawconfig = proxy.GetConfig()
+ rawconfig = proxy.GetConfig().encode('UTF-8')
except xmlrpclib.Fault:
self.logger.error("Failed to download configuration from Bcfg2")
raise SystemExit(2)
@@ -252,7 +262,7 @@ class Client:
if self.setup['cache']:
try:
- open(self.setup['cache'], 'w').write(rawconfig.encode(self.setup['encoding']))
+ open(self.setup['cache'], 'w').write(rawconfig)
os.chmod(self.setup['cache'], 33152)
except IOError:
self.logger.warning("Failed to write config cache file %s" %
diff --git a/src/sbin/bcfg2-info b/src/sbin/bcfg2-info
index 161fee441..07953ae69 100755
--- a/src/sbin/bcfg2-info
+++ b/src/sbin/bcfg2-info
@@ -375,21 +375,21 @@ class infoCore(cmd.Cmd, Bcfg2.Server.Core.Core):
except:
print("Client %s not defined" % client)
continue
- print("Hostname:\t", client_meta.hostname)
- print("Profile:\t", client_meta.profile)
- print("Groups:\t\t", list(client_meta.groups)[0])
+ print("Hostname:\t%s" % client_meta.hostname)
+ print("Profile:\t%s" % client_meta.profile)
+ print("Groups:\t\t%s" % list(client_meta.groups)[0])
for grp in list(client_meta.groups)[1:]:
- print('\t\t%s' % grp)
+ print("\t\t%s" % grp)
if client_meta.bundles:
- print("Bundles:\t", list(client_meta.bundles)[0])
+ print("Bundles:\t%s" % list(client_meta.bundles)[0])
for bnd in list(client_meta.bundles)[1:]:
- print('\t\t%s' % bnd)
+ print("\t\t%s" % bnd)
if client_meta.connectors:
print("Connector data")
print("=" * 80)
for conn in client_meta.connectors:
if getattr(client_meta, conn):
- print("%s:\t" % (conn), getattr(client_meta, conn))
+ print("%s:\t%s" % (conn, getattr(client_meta, conn)))
print("=" * 80)
def do_mappings(self, args):
@@ -487,7 +487,10 @@ if __name__ == '__main__':
})
setup = Bcfg2.Options.OptionParser(optinfo)
setup.parse(sys.argv[1:])
- if setup['profile'] and have_profile:
+ if setup['args'] and setup['args'][0] == 'help':
+ print(USAGE)
+ sys.exit(0)
+ elif setup['profile'] and have_profile:
prof = profile.Profile()
loop = prof.runcall(infoCore, setup['repo'], setup['plugins'],
setup['password'], setup['encoding'],
diff --git a/src/sbin/bcfg2-lint b/src/sbin/bcfg2-lint
index 6bc34433e..464e839e5 100755
--- a/src/sbin/bcfg2-lint
+++ b/src/sbin/bcfg2-lint
@@ -50,10 +50,13 @@ def run_plugin(plugin, plugin_name, setup=None, errorhandler=None,
errorhandler = get_errorhandler(config)
if config is not None and config.has_section(plugin_name):
- args.append(dict(config.items(plugin_name), **setup))
+ arg = setup
+ for key, val in config.items(plugin_name):
+ arg[key] = val
+ args.append(arg)
else:
args.append(setup)
-
+
# older versions of python do not support mixing *-magic and
# non-*-magic (e.g., "plugin(*args, files=files)", so we do this
# all with *-magic
@@ -181,8 +184,20 @@ if __name__ == '__main__':
config=config, setup=setup)
if serverplugins:
- run_server_plugins(serverplugins, errorhandler=errorhandler,
- config=config, setup=setup)
+ if errorhandler.errors:
+ # it would be swell if we could try to start the server
+ # even if there were errors with the serverless plugins,
+ # but since XML parsing errors occur in the FAM thread
+ # (not in the core server thread), there's no way we can
+ # start the server and try to catch exceptions --
+ # bcfg2-lint isn't in the same stack as the exceptions.
+ # so we're forced to assume that a serverless plugin error
+ # will prevent the server from starting
+ print("Serverless plugins encountered errors, skipping server "
+ "plugins")
+ else:
+ run_server_plugins(serverplugins, errorhandler=errorhandler,
+ config=config, setup=setup)
if errorhandler.errors or errorhandler.warnings or setup['verbose']:
print("%d errors" % errorhandler.errors)
diff --git a/src/sbin/bcfg2-reports b/src/sbin/bcfg2-reports
index 20288fc5e..9a4c6e60d 100755
--- a/src/sbin/bcfg2-reports
+++ b/src/sbin/bcfg2-reports
@@ -1,4 +1,4 @@
-#! /usr/bin/env python
+#!/usr/bin/env python
"""Query reporting system for client status."""
__revision__ = '$Revision$'
@@ -47,6 +47,23 @@ def statecompare(client1, client2):
else:
return 0
+def totalcompare(client1, client2):
+ """Compares two clients by their total entry counts."""
+ return cmp(client2.current_interaction.totalcount, \
+ client1.current_interaction.totalcount)
+
+def goodcompare(client1, client2):
+ """Compares two clients by their good entry counts."""
+ return cmp(client2.current_interaction.goodcount, \
+ client1.current_interaction.goodcount)
+
+def badcompare(client1, client2):
+ """Compares two clients by their bad entry counts."""
+ return cmp(client2.current_interaction.totalcount - \
+ client2.current_interaction.goodcount, \
+ client1.current_interaction.totalcount - \
+ client1.current_interaction.goodcount)
+
def crit_compare(criterion, client1, client2):
"""Compares two clients by the criteria provided in criterion."""
for crit in criterion:
@@ -57,6 +74,12 @@ def crit_compare(criterion, client1, client2):
comp = statecompare(client1, client2)
elif crit == 'time':
comp = timecompare(client1, client2)
+ elif crit == 'total':
+ comp = totalcompare(client1, client2)
+ elif crit == 'good':
+ comp = goodcompare(client1, client2)
+ elif crit == 'bad':
+ comp = badcompare(client1, client2)
if comp != 0:
return comp
@@ -83,6 +106,13 @@ def print_fields(fields, cli, max_name, entrydict):
fdata.append("clean")
else:
fdata.append("dirty")
+ elif field == 'total':
+ fdata.append("%5d" % cli.current_interaction.totalcount)
+ elif field == 'good':
+ fdata.append("%5d" % cli.current_interaction.goodcount)
+ elif field == 'bad':
+ fdata.append("%5d" % cli.current_interaction.totalcount \
+ - cli.current_interaction.goodcount)
else:
try:
fdata.append(getattr(cli, field))
@@ -104,6 +134,7 @@ def print_entry(item, max_name):
fields = ""
sort = ""
badentry = ""
+modifiedentry = ""
extraentry = ""
expire = ""
singlehost = ""
@@ -114,8 +145,8 @@ result = list()
entrydict = dict()
args = sys.argv[1:]
-opts, pargs = getopt(args, 'ab:cde:hs:x:',
- ['stale', 'sort=', 'fields=', 'badentry=', 'extraentry='])
+opts, pargs = getopt(args, 'ab:cde:hm:s:t:x:',
+ ['stale', 'sort=', 'fields=', 'badentry=', 'modifiedentry=', 'extraentry='])
for option in opts:
if len(option) > 0:
@@ -125,11 +156,17 @@ for option in opts:
sort = option[1]
if option[0] == '--badentry':
badentry = option[1]
+ if option[0] == '--modifiedentry':
+ modifiedentry = option[1]
if option[0] == '--extraentry':
extraentry = option[1]
if option[0] == '-x':
expire = option[1]
- if option[0] == '-s' or option[0] == '-b' or option[0] == '-e':
+ if option[0] == '-s' or \
+ option[0] == '-t' or \
+ option[0] == '-b' or \
+ option[0] == '-m' or \
+ option[0] == '-e':
singlehost = option[1]
if expire != "":
@@ -147,33 +184,45 @@ elif '-h' in args:
print("""Usage: bcfg2-reports [option] ...
Options and arguments (and corresponding environment variables):
--a : shows all hosts, including expired hosts
--b NAME : single-host mode - shows bad entries from the
- current interaction of NAME
--c : shows only clean hosts
--d : shows only dirty hosts
--e NAME : single-host mode - shows extra entries from the
- current interaction of NAME
--h : shows help and usage info about bcfg2-reports
--s NAME : single-host mode - shows bad and extra entries from
- the current interaction of NAME
--x NAME : toggles expired/unexpired state of NAME
---badentry=KIND,NAME : shows only hosts whose current interaction has bad
- entries in of KIND kind and NAME name; if a single
- argument ARG1 is given, then KIND,NAME pairs will be
- read from a file of name ARG1
---extraentry=KIND,NAME : shows only hosts whose current interaction has extra
- entries in of KIND kind and NAME name; if a single
- argument ARG1 is given, then KIND,NAME pairs will be
- read from a file of name ARG1
---fields=ARG1,ARG2,... : only displays the fields ARG1,ARG2,...
- (name,time,state)
---sort=ARG1,ARG2,... : sorts output on ARG1,ARG2,... (name,time,state)
---stale : shows hosts which haven't run in the last 24 hours
+-a : shows all hosts, including expired hosts
+-b NAME : single-host mode - shows bad entries from the
+ current interaction of NAME
+-c : shows only clean hosts
+-d : shows only dirty hosts
+-e NAME : single-host mode - shows extra entries from the
+ current interaction of NAME
+-h : shows help and usage info about bcfg2-reports
+-m NAME : single-host mode - shows modified entries from the
+ current interaction of NAME
+-s NAME : single-host mode - shows bad, modified, and extra
+ entries from the current interaction of NAME
+-t NAME : single-host mode - shows total number of managed and
+ good entries from the current interaction of NAME
+-x NAME : toggles expired/unexpired state of NAME
+--badentry=KIND,NAME : shows only hosts whose current interaction has bad
+ entries in of KIND kind and NAME name; if a single
+ argument ARG1 is given, then KIND,NAME pairs will be
+ read from a file of name ARG1
+--modifiedentry=KIND,NAME : shows only hosts whose current interaction has
+ modified entries in of KIND kind and NAME name; if a
+ single argument ARG1 is given, then KIND,NAME pairs
+ will be read from a file of name ARG1
+--extraentry=KIND,NAME : shows only hosts whose current interaction has extra
+ entries in of KIND kind and NAME name; if a single
+ argument ARG1 is given, then KIND,NAME pairs will be
+ read from a file of name ARG1
+--fields=ARG1,ARG2,... : only displays the fields ARG1,ARG2,...
+ (name,time,state)
+--sort=ARG1,ARG2,... : sorts output on ARG1,ARG2,... (name,time,state)
+--stale : shows hosts which haven't run in the last 24 hours
""")
elif singlehost != "":
for c_inst in c_list:
if singlehost == c_inst.name:
+ if '-t' in args:
+ managed = c_inst.current_interaction.totalcount
+ good = c_inst.current_interaction.goodcount
+ print("Total managed entries: %d (good: %d)" % (managed, good))
baditems = c_inst.current_interaction.bad()
if len(baditems) > 0 and ('-b' in args or '-s' in args):
print("Bad Entries:")
@@ -183,6 +232,15 @@ elif singlehost != "":
max_name = len(item.entry.name)
for item in baditems:
print_entry(item, max_name)
+ modifieditems = c_inst.current_interaction.modified()
+ if len(modifieditems) > 0 and ('-m' in args or '-s' in args):
+ print "Modified Entries:"
+ max_name = -1
+ for item in modifieditems:
+ if len(item.entry.name) > max_name:
+ max_name = len(item.entry.name)
+ for item in modifieditems:
+ print_entry(item, max_name)
extraitems = c_inst.current_interaction.extra()
if len(extraitems) > 0 and ('-e' in args or '-s' in args):
print("Extra Entries:")
@@ -206,6 +264,9 @@ else:
if badentry != "":
badentry = badentry.split(',')
+ if modifiedentry != "":
+ modifiedentry = modifiedentry.split(',')
+
if extraentry != "":
extraentry = extraentry.split(',')
@@ -233,7 +294,7 @@ else:
for c_inst in c_list:
baditems = c_inst.current_interaction.bad()
for item in baditems:
- if item.name == badentry[1] and item.kind == badentry[0]:
+ if item.entry.name == badentry[1] and item.entry.kind == badentry[0]:
result.append(c_inst)
if c_inst in entrydict:
entrydict.get(c_inst).append(badentry[1])
@@ -244,7 +305,29 @@ else:
for c_inst in c_list:
baditems = c_inst.current_interaction.bad()
for item in baditems:
- if item.name == badentry[1] and item.kind == badentry[0]:
+ if item.entry.name == badentry[1] and item.entry.kind == badentry[0]:
+ result.append(c_inst)
+ break
+ elif modifiedentry != "":
+ if len(modifiedentry) == 1:
+ fileread = fileinput.input(modifiedentry[0])
+ for line in fileread:
+ modifiedentry = line.strip().split(',')
+ for c_inst in c_list:
+ modifieditems = c_inst.current_interaction.modified()
+ for item in modifieditems:
+ if item.entry.name == modifiedentry[1] and item.entry.kind == modifiedentry[0]:
+ result.append(c_inst)
+ if c_inst in entrydict:
+ entrydict.get(c_inst).append(modifiedentry[1])
+ else:
+ entrydict[c_inst] = [modifiedentry[1]]
+ break
+ else:
+ for c_inst in c_list:
+ modifieditems = c_inst.current_interaction.modified()
+ for item in modifieditems:
+ if item.entry.name == modifiedentry[1] and item.entry.kind == modifiedentry[0]:
result.append(c_inst)
break
elif extraentry != "":
@@ -255,7 +338,7 @@ else:
for c_inst in c_list:
extraitems = c_inst.current_interaction.extra()
for item in extraitems:
- if item.name == extraentry[1] and item.kind == extraentry[0]:
+ if item.entry.name == extraentry[1] and item.entry.kind == extraentry[0]:
result.append(c_inst)
if c_inst in entrydict:
entrydict.get(c_inst).append(extraentry[1])
@@ -266,7 +349,7 @@ else:
for c_inst in c_list:
extraitems = c_inst.current_interaction.extra()
for item in extraitems:
- if item.name == extraentry[1] and item.kind == extraentry[0]:
+ if item.entry.name == extraentry[1] and item.entry.kind == extraentry[0]:
result.append(c_inst)
break
diff --git a/src/sbin/bcfg2-server b/src/sbin/bcfg2-server
index f4bd5e5b7..546d5a249 100755
--- a/src/sbin/bcfg2-server
+++ b/src/sbin/bcfg2-server
@@ -35,6 +35,7 @@ if __name__ == '__main__':
OPTINFO.update({'key' : Bcfg2.Options.SERVER_KEY,
'cert' : Bcfg2.Options.SERVER_CERT,
'ca' : Bcfg2.Options.SERVER_CA,
+ 'listen_all' : Bcfg2.Options.SERVER_LISTEN_ALL,
'location' : Bcfg2.Options.SERVER_LOCATION,
'passwd' : Bcfg2.Options.SERVER_PASSWORD,
'static' : Bcfg2.Options.SERVER_STATIC,
@@ -51,6 +52,7 @@ if __name__ == '__main__':
print("Could not read %s" % setup['configfile'])
sys.exit(1)
Bcfg2.Component.run_component(Bcfg2.Server.Core.Core,
+ listen_all=setup['listen_all'],
location=setup['location'],
daemon = setup['daemon'],
pidfile_name = setup['daemon'],