432
431
"created", "enabled", "fingerprint",
433
432
"host", "interval", "last_checked_ok",
434
433
"last_enabled", "name", "timeout")
434
client_defaults = { "timeout": "5m",
435
"extended_timeout": "15m",
437
"checker": "fping -q -- %%(host)s",
439
"approval_delay": "0s",
440
"approval_duration": "1s",
441
"approved_by_default": "True",
436
445
def timeout_milliseconds(self):
437
446
"Return the 'timeout' attribute in milliseconds"
448
457
def approval_delay_milliseconds(self):
449
458
return timedelta_to_milliseconds(self.approval_delay)
451
def __init__(self, name = None, config=None):
461
def config_parser(config):
462
""" Construct a new dict of client settings of this form:
463
{ client_name: {setting_name: value, ...}, ...}
464
with exceptions for any special settings as defined above"""
466
for client_name in config.sections():
467
section = dict(config.items(client_name))
468
client = settings[client_name] = {}
470
# Default copying each value from config to new dict
471
for setting, value in section.iteritems():
472
client[setting] = value
474
# Reformat values from string types to Python types
475
client["approved_by_default"] = config.getboolean(
476
client_name, "approved_by_default")
477
client["enabled"] = config.getboolean(client_name, "enabled")
479
client["fingerprint"] = (section["fingerprint"].upper()
481
if "secret" in section:
482
client["secret"] = section["secret"].decode("base64")
483
elif "secfile" in section:
484
with open(os.path.expanduser(os.path.expandvars
485
(section["secfile"])),
487
client["secret"] = secfile.read()
489
raise TypeError("No secret or secfile for section %s"
491
client["timeout"] = string_to_delta(section["timeout"])
492
client["extended_timeout"] = string_to_delta(
493
section["extended_timeout"])
494
client["interval"] = string_to_delta(section["interval"])
495
client["approval_delay"] = string_to_delta(
496
section["approval_delay"])
497
client["approval_duration"] = string_to_delta(
498
section["approval_duration"])
503
def __init__(self, config, name = None):
452
504
"""Note: the 'checker' key in 'config' sets the
453
505
'checker_command' attribute and *not* the 'checker'
458
508
logger.debug("Creating client %r", self.name)
459
509
# Uppercase and remove spaces from fingerprint for later
460
510
# comparison purposes with return value from the fingerprint()
462
self.fingerprint = (config["fingerprint"].upper()
512
self.fingerprint = config["fingerprint"]
464
513
logger.debug(" Fingerprint: %s", self.fingerprint)
465
if "secret" in config:
466
self.secret = config["secret"].decode("base64")
467
elif "secfile" in config:
468
with open(os.path.expanduser(os.path.expandvars
469
(config["secfile"])),
471
self.secret = secfile.read()
473
raise TypeError("No secret or secfile for client %s"
475
self.host = config.get("host", "")
514
self.secret = config["secret"]
515
self.host = config["host"]
476
516
self.created = datetime.datetime.utcnow()
477
self.enabled = config.get("enabled", True)
517
self.enabled = config["enabled"]
478
518
self.last_approval_request = None
480
520
self.last_enabled = datetime.datetime.utcnow()
482
522
self.last_enabled = None
483
523
self.last_checked_ok = None
484
524
self.last_checker_status = None
485
self.timeout = string_to_delta(config["timeout"])
486
self.extended_timeout = string_to_delta(config
487
["extended_timeout"])
488
self.interval = string_to_delta(config["interval"])
525
self.timeout = config["timeout"]
526
self.extended_timeout = config["extended_timeout"]
527
self.interval = config["interval"]
489
528
self.checker = None
490
529
self.checker_initiator_tag = None
491
530
self.disable_initiator_tag = None
497
536
self.checker_command = config["checker"]
498
537
self.current_checker_command = None
499
538
self.approved = None
500
self.approved_by_default = config.get("approved_by_default",
539
self.approved_by_default = config["approved_by_default"]
502
540
self.approvals_pending = 0
503
self.approval_delay = string_to_delta(
504
config["approval_delay"])
505
self.approval_duration = string_to_delta(
506
config["approval_duration"])
541
self.approval_delay = config["approval_delay"]
542
self.approval_duration = config["approval_duration"]
507
543
self.changedstate = (multiprocessing_manager
508
544
.Condition(multiprocessing_manager
2065
2101
% server_settings["servicename"]))
2067
2103
# Parse config file with clients
2068
client_defaults = { "timeout": "5m",
2069
"extended_timeout": "15m",
2071
"checker": "fping -q -- %%(host)s",
2073
"approval_delay": "0s",
2074
"approval_duration": "1s",
2076
client_config = configparser.SafeConfigParser(client_defaults)
2104
client_config = configparser.SafeConfigParser(Client.client_defaults)
2077
2105
client_config.read(os.path.join(server_settings["configdir"],
2078
2106
"clients.conf"))
2180
2208
client_class = functools.partial(ClientDBusTransitional,
2183
special_settings = {
2184
# Some settings need to be accessd by special methods;
2185
# booleans need .getboolean(), etc. Here is a list of them:
2186
"approved_by_default":
2188
client_config.getboolean(section, "approved_by_default"),
2191
client_config.getboolean(section, "enabled"),
2193
# Construct a new dict of client settings of this form:
2194
# { client_name: {setting_name: value, ...}, ...}
2195
# with exceptions for any special settings as defined above
2196
client_settings = dict((clientname,
2199
if setting not in special_settings
2200
else special_settings[setting]
2202
for setting, value in
2203
client_config.items(clientname)))
2204
for clientname in client_config.sections())
2211
client_settings = Client.config_parser(client_config)
2206
2212
old_client_settings = {}
2207
2213
clients_data = []
2243
2249
# Clients who has passed its expire date can still be
2244
# enabled if its last checker was sucessful. Clients
2250
# enabled if its last checker was successful. Clients
2245
2251
# whose checker failed before we stored its state is
2246
2252
# assumed to have failed all checkers during downtime.
2247
2253
if client["enabled"]:
2248
if client["expires"] <= (datetime.datetime
2250
# Client has expired
2251
if client["last_checker_status"] != 0:
2254
if datetime.datetime.utcnow() >= client["expires"]:
2255
if not client["last_checked_ok"]:
2257
"disabling client {0} - Client never "
2258
"performed a successfull checker"
2259
.format(client["name"]))
2260
client["enabled"] = False
2261
elif client["last_checker_status"] != 0:
2263
"disabling client {0} - Client "
2264
"last checker failed with error code {1}"
2265
.format(client["name"],
2266
client["last_checker_status"]))
2252
2267
client["enabled"] = False
2254
2269
client["expires"] = (datetime.datetime