Skip to content
Snippets Groups Projects
Commit f49ebce6 authored by Pavel Kácha's avatar Pavel Kácha
Browse files

Some PEP8 fixes

parent 0adffa59
Branches
Tags
No related merge requests found
......@@ -32,6 +32,7 @@ from jsonschema import Draft4Validator
VERSION = "3.0-beta2"
class Error(Exception):
def __init__(self, method=None, req_id=None, errors=None, **kwargs):
......@@ -41,11 +42,9 @@ class Error(Exception):
if errors:
self.errors.extend(errors)
def append(self, _events=None, **kwargs):
self.errors.append(kwargs)
def get_http_err_msg(self):
try:
err = self.errors[0]["error"]
......@@ -64,11 +63,9 @@ class Error(Exception):
msg = "Multiple errors"
return err, msg
def __str__(self):
return "\n".join(self.str_err(e) for e in self.errors)
def log(self, logger, prio=logging.ERROR):
for e in self.errors:
logger.log(prio, self.str_err(e))
......@@ -79,7 +76,6 @@ class Error(Exception):
if debug:
logger.debug(debug)
def str_err(self, e):
out = []
out.append("Error(%s) %s " % (e.get("error", 0), e.get("message", "Unknown error")))
......@@ -87,7 +83,6 @@ class Error(Exception):
out.append("(cause was %s: %s)" % (e["exc"][0].__name__, str(e["exc"][1])))
return "".join(out)
def str_info(self, e):
ecopy = dict(e) # shallow copy
ecopy.pop("req_id", None)
......@@ -101,7 +96,6 @@ class Error(Exception):
out = ""
return out
def str_debug(self, e):
out = []
if not "exc" in e or not e["exc"]:
......@@ -112,7 +106,6 @@ class Error(Exception):
out.extend(format_tb(exc_tb))
return "".join(out)
def to_dict(self):
errlist = []
for e in self.errors:
......@@ -127,7 +120,6 @@ class Error(Exception):
return d
def get_clean_root_logger(level=logging.INFO):
""" Attempts to get logging module into clean slate state """
......@@ -149,7 +141,6 @@ def get_clean_root_logger(level=logging.INFO):
return logger
def StreamLogger(stream=sys.stderr, level=logging.DEBUG):
""" Fallback handler just for setup, not meant to be used from
configuration file because during wsgi query stdout/stderr
......@@ -164,7 +155,6 @@ def StreamLogger(stream=sys.stderr, level=logging.DEBUG):
return logger
class LogRequestFilter(logging.Filter):
""" Filter class, instance of which is added to logger class to add
info about request automatically into every logline, no matter
......@@ -175,7 +165,6 @@ class LogRequestFilter(logging.Filter):
logging.Filter.__init__(self)
self.req = req
def filter(self, record):
if self.req.env:
record.req_preamble = "%08x/%s: " % (self.req.req_id or 0, self.req.path)
......@@ -184,7 +173,6 @@ class LogRequestFilter(logging.Filter):
return True
def FileLogger(req, filename, level=logging.INFO):
fhand = logging.FileHandler(filename)
......@@ -198,7 +186,6 @@ def FileLogger(req, filename, level=logging.INFO):
return logger
def SysLogger(req, socket="/dev/log", facility=logging.handlers.SysLogHandler.LOG_DAEMON, level=logging.INFO):
fhand = logging.handlers.SysLogHandler(address=socket, facility=facility)
......@@ -208,13 +195,13 @@ def SysLogger(req, socket="/dev/log", facility=logging.handlers.SysLogHandler.LO
logger = get_clean_root_logger(level)
logger.addFilter(ffilt)
logger.addHandler(fhand)
logger.info("Initialized SysLogger(req=%s, socket=\"%s\", facility=\"%d\", level=\"%d\")" % (type(req).__name__, socket, facility, level))
logger.info("Initialized SysLogger(req=%s, socket=\"%s\", facility=\"%d\", level=\"%d\")" % (
type(req).__name__, socket, facility, level))
return logger
Client = namedtuple("Client",
["id", "registered", "requestor", "hostname", "name",
Client = namedtuple("Client", [
"id", "registered", "requestor", "hostname", "name",
"secret", "valid", "read", "debug", "write", "test", "note"])
......@@ -224,7 +211,6 @@ class Object(object):
return "%s()" % type(self).__name__
class Request(Object):
""" Simple container for info about ongoing request.
One instance gets created before server startup, and all other
......@@ -246,11 +232,9 @@ class Request(Object):
Object.__init__(self)
self.reset()
def __str__(self):
return "%s(env='%s', client='%s')" % (type(self).__name__, str(self.env), str(self.client))
def reset(self, env=None, client=None, path=None, req_id=None):
self.env = env
self.client = client
......@@ -260,12 +244,10 @@ class Request(Object):
else:
self.req_id = 0 if env is None else randint(0x00000000, 0xFFFFFFFF)
def error(self, **kwargs):
return Error(self.path, self.req_id, **kwargs)
class ObjectBase(Object):
def __init__(self, req, log):
......@@ -273,23 +255,19 @@ class ObjectBase(Object):
self.req = req
self.log = log
def __str__(self):
return "%s(req=%s)" % (type(self).__name__, type(self.req).__name__)
class PlainAuthenticator(ObjectBase):
def __init__(self, req, log, db):
ObjectBase.__init__(self, req, log)
self.db = db
def __str__(self):
return "%s(req=%s, db=%s)" % (type(self).__name__, type(self.req).__name__, type(self.db).__name__)
def authenticate(self, env, args, hostnames=None, check_secret=True):
name = args.get("client", [None])[0]
secret = args.get("secret", [None])[0] if check_secret else None
......@@ -315,7 +293,6 @@ class PlainAuthenticator(ObjectBase):
return client
def authorize(self, env, client, path, method):
if method.debug:
if not client.debug:
......@@ -357,17 +334,17 @@ class X509Authenticator(PlainAuthenticator):
firstcommon = commons[0]
return [firstcommon] + list(set(altnames+commons) - set([firstcommon]))
def is_verified_by_apache(self, env, args):
# Allows correct work while SSLVerifyClient both "optional" and "required"
verify = env.get("SSL_CLIENT_VERIFY")
if verify == "SUCCESS":
return True
exception = self.req.error(message="authenticate: certificate verification failed", error=403, args = args, ssl_client_verify=verify, cert=env.get("SSL_CLIENT_CERT"))
exception = self.req.error(
message="authenticate: certificate verification failed",
error=403, args=args, ssl_client_verify=verify, cert=env.get("SSL_CLIENT_CERT"))
exception.log(self.log)
return False
def authenticate(self, env, args):
if not self.is_verified_by_apache(env, args):
return None
......@@ -375,7 +352,9 @@ class X509Authenticator(PlainAuthenticator):
try:
cert_names = self.get_cert_dns_names(env["SSL_CLIENT_CERT"])
except:
exception = self.req.error(message="authenticate: cannot get or parse certificate from env", error=403, exc=sys.exc_info(), env=env)
exception = self.req.error(
message="authenticate: cannot get or parse certificate from env",
error=403, exc=sys.exc_info(), env=env)
exception.log(self.log)
return None
......@@ -391,12 +370,16 @@ class X509NameAuthenticator(X509Authenticator):
try:
cert_name = env["SSL_CLIENT_S_DN_CN"]
except:
exception = self.req.error(message="authenticate: cannot get or parse certificate from env", error=403, exc=sys.exc_info(), env=env)
exception = self.req.error(
message="authenticate: cannot get or parse certificate from env",
error=403, exc=sys.exc_info(), env=env)
exception.log(self.log)
return None
if cert_name != args.setdefault("client", [cert_name])[0]:
exception = self.req.error(message="authenticate: client name does not correspond with certificate", error=403, cn = cert_name, args = args)
exception = self.req.error(
message="authenticate: client name does not correspond with certificate",
error=403, cn=cert_name, args=args)
exception.log(self.log)
return None
......@@ -410,7 +393,6 @@ class X509MixMatchAuthenticator(X509Authenticator):
self.hostname_auth = X509Authenticator(req, log, db)
self.name_auth = X509NameAuthenticator(req, log, db)
def authenticate(self, env, args):
if not self.is_verified_by_apache(env, args):
return None
......@@ -418,7 +400,9 @@ class X509MixMatchAuthenticator(X509Authenticator):
try:
cert_name = env["SSL_CLIENT_S_DN_CN"]
except:
exception = self.req.error(message="authenticate: cannot get or parse certificate from env", error=403, exc=sys.exc_info(), env=env)
exception = self.req.error(
message="authenticate: cannot get or parse certificate from env",
error=403, exc=sys.exc_info(), env=env)
exception.log(self.log)
return None
name = args.get("client", [None])[0]
......@@ -447,11 +431,9 @@ class NoValidator(ObjectBase):
def __init__(self, req, log):
ObjectBase.__init__(self, req, log)
def __str__(self):
return "%s(req=%s)" % (type(self).__name__, type(self.req).__name__)
def check(self, event):
return []
......@@ -465,11 +447,9 @@ class JSONSchemaValidator(NoValidator):
self.schema = json.load(f)
self.validator = Draft4Validator(self.schema)
def __str__(self):
return "%s(req=%s, filename=\"%s\")" % (type(self).__name__, type(self.req).__name__, self.path)
def check(self, event):
def sortkey(k):
......@@ -490,10 +470,10 @@ class JSONSchemaValidator(NoValidator):
return res
class MySQL(ObjectBase):
def __init__(self, req, log, host, user, password, dbname, port, retry_count,
def __init__(
self, req, log, host, user, password, dbname, port, retry_count,
retry_pause, event_size_limit, catmap_filename, tagmap_filename):
ObjectBase.__init__(self, req, log)
self.host = host
......@@ -518,17 +498,18 @@ class MySQL(ObjectBase):
self.con = None
def __str__(self):
return "%s(req=%s, host='%s', user='%s', dbname='%s', port=%d, retry_count=%d, retry_pause=%d, catmap_filename=\"%s\", tagmap_filename=\"%s\")" % (
type(self).__name__, type(self.req).__name__, self.host, self.user, self.dbname, self.port, self.retry_count, self.retry_pause, self.catmap_filename, self.tagmap_filename)
return (
"%s(req=%s, host='%s', user='%s', dbname='%s', port=%d, retry_count=%d, "
"retry_pause=%d, catmap_filename=\"%s\", tagmap_filename=\"%s\")") % (
type(self).__name__, type(self.req).__name__, self.host, self.user, self.dbname, self.port, self.retry_count,
self.retry_pause, self.catmap_filename, self.tagmap_filename)
def connect(self):
self.con = my.connect(host=self.host, user=self.user, passwd=self.password,
self.con = my.connect(
host=self.host, user=self.user, passwd=self.password,
db=self.dbname, port=self.port, cursorclass=mycursors.DictCursor)
def close(self):
try:
if self.con:
......@@ -537,10 +518,8 @@ class MySQL(ObjectBase):
pass
self.con = None
__del__ = close
def repeat(self):
""" Allows for graceful repeating of transactions self.retry_count
times. Unsuccessful attempts wait for self.retry_pause until
......@@ -563,7 +542,6 @@ class MySQL(ObjectBase):
self.retry_attempt -= 1
yield self
def __enter__(self):
""" Context manager protocol. Guarantees that transaction will
get either commited or rolled back in case of database
......@@ -580,7 +558,6 @@ class MySQL(ObjectBase):
self.retry_attempt = 0
return self
def __exit__(self, exc_type, exc_val, exc_tb):
""" Context manager protocol. If db exception is fired and
self.retry_attempt is not zero, it is only logged and
......@@ -605,7 +582,6 @@ class MySQL(ObjectBase):
self.log.info("Database error (%d attempts left): %s %s" % (self.retry_attempt, exc_type.__name__, exc_val))
return True
def query(self, *args, **kwargs):
if not self.con:
self.connect()
......@@ -614,15 +590,12 @@ class MySQL(ObjectBase):
crs.execute(*args, **kwargs)
return crs
def _get_comma_perc(self, l):
return ','.join(['%s'] * len(l))
def _get_not(self, b):
return "" if b else "NOT"
def get_client_by_name(self, cert_names=None, name=None, secret=None):
query = ["SELECT * FROM clients WHERE valid = 1"]
params = []
......@@ -639,15 +612,14 @@ class MySQL(ObjectBase):
for attempt in self.repeat():
with attempt as db:
rows = db.query("".join(query), params).fetchall()
if len(rows) > 1:
self.log.warn("get_client_by_name: query returned more than one result (cert_names = %s, name = %s, secret = %s): %s" % (cert_names, name, secret, ", ".join([str(Client(**row)) for row in rows])))
self.log.warn(
"get_client_by_name: query returned more than one result (cert_names = %s, name = %s, secret = %s): %s" % (
cert_names, name, secret, ", ".join([str(Client(**row)) for row in rows])))
return None
return Client(**rows[0]) if rows else None
def get_clients(self, id=None):
query = ["SELECT * FROM clients"]
params = []
......@@ -660,7 +632,6 @@ class MySQL(ObjectBase):
rows = db.query(" ".join(query), params).fetchall()
return [Client(**row) for row in rows]
def add_modify_client(self, id=None, **kwargs):
query = []
params = []
......@@ -689,7 +660,6 @@ class MySQL(ObjectBase):
newid = crs.lastrowid if id is None else id
return newid
def get_debug(self):
for attempt in self.repeat():
with attempt as db:
......@@ -701,33 +671,36 @@ class MySQL(ObjectBase):
"tables": tablestat
}
def getMaps(self, section, variables):
maps = []
for v in variables:
try:
mapped = section[v]
except KeyError:
raise self.req.error(message="Wrong tag or category used in query.", error=422,
exc=sys.exc_info(), key=v)
raise self.req.error(
message="Wrong tag or category used in query.",
error=422, exc=sys.exc_info(), key=v)
maps.append(mapped)
return set(maps) # unique
def fetch_events(self, client, id, count,
def fetch_events(
self, client, id, count,
cat=None, nocat=None,
tag=None, notag=None,
group=None, nogroup=None):
if cat and nocat:
raise self.req.error(message="Unrealizable conditions. Choose cat or nocat option.", error=422,
cat=cat, nocat=nocat)
raise self.req.error(
message="Unrealizable conditions. Choose cat or nocat option.",
error=422, cat=cat, nocat=nocat)
if tag and notag:
raise self.req.error(message="Unrealizable conditions. Choose tag or notag option.", error=422,
tag=tag, notag=notag)
raise self.req.error(
message="Unrealizable conditions. Choose tag or notag option.",
error=422, tag=tag, notag=notag)
if group and nogroup:
raise self.req.error(message="Unrealizable conditions. Choose group or nogroup option.", error=422,
group=group, nogroup=nogroup)
raise self.req.error(
message="Unrealizable conditions. Choose group or nogroup option.",
error=422, group=group, nogroup=nogroup)
query = ["SELECT e.id, e.data FROM clients c RIGHT JOIN events e ON c.id = e.client_id WHERE e.id > %s"]
params = [id or 0]
......@@ -779,8 +752,9 @@ class MySQL(ObjectBase):
# Note that we use Error object just for proper formatting,
# but do not raise it; from client perspective invalid
# events get skipped silently.
err = self.req.error(message="Unable to deserialize JSON event from db, id=%s" % r["id"], error=500,
exc=sys.exc_info(), id=r["id"])
err = self.req.error(
message="Unable to deserialize JSON event from db, id=%s" % r["id"],
error=500, exc=sys.exc_info(), id=r["id"])
err.log(self.log, prio=logging.WARNING)
events.append(e)
......@@ -789,13 +763,13 @@ class MySQL(ObjectBase):
"events": events
}
def store_events(self, client, events, events_raw):
try:
for attempt in self.repeat():
with attempt as db:
for event, raw_event in zip(events, events_raw):
lastid = db.query("INSERT INTO events (received,client_id,data) VALUES (NOW(), %s, %s)",
lastid = db.query(
"INSERT INTO events (received,client_id,data) VALUES (NOW(), %s, %s)",
(client.id, raw_event)).lastrowid
catlist = event.get('Category', ["Other"])
......@@ -817,37 +791,36 @@ class MySQL(ObjectBase):
exception.log(self.log)
return [{"error": 500, "message": "DB error %s" % type(e).__name__}]
def insertLastReceivedId(self, client, id):
self.log.debug("insertLastReceivedId: id %i for client %i(%s)" % (id, client.id, client.hostname))
for attempt in self.repeat():
with attempt as db:
db.query("INSERT INTO last_events(client_id, event_id, timestamp) VALUES(%s, %s, NOW())", (client.id, id))
def getLastEventId(self):
for attempt in self.repeat():
with attempt as db:
row = db.query("SELECT MAX(id) as id FROM events").fetchall()[0]
return row['id'] or 1
def getLastReceivedId(self, client):
for attempt in self.repeat():
with attempt as db:
res = db.query("SELECT event_id as id FROM last_events WHERE client_id = %s ORDER BY last_events.id DESC LIMIT 1", (client.id,)).fetchall()
res = db.query(
"SELECT event_id as id FROM last_events WHERE client_id = %s ORDER BY last_events.id DESC LIMIT 1",
(client.id,)).fetchall()
try:
row = res[0]
except IndexError:
id = None
self.log.debug("getLastReceivedId: probably first access, unable to get id for client %i(%s)" % (client.id, client.hostname))
self.log.debug("getLastReceivedId: probably first access, unable to get id for client %i(%s)" % (
client.id, client.hostname))
else:
id = row["id"]
self.log.debug("getLastReceivedId: id %i for client %i(%s)" % (id, client.id, client.hostname))
return id
def load_maps(self):
with self as db:
db.query("DELETE FROM tags")
......@@ -858,10 +831,10 @@ class MySQL(ObjectBase):
catsplit = cat_subcat.split(".", 1)
category = catsplit[0]
subcategory = catsplit[1] if len(catsplit) > 1 else None
db.query("INSERT INTO categories(id, category, subcategory, cat_subcat) VALUES (%s, %s, %s, %s)",
db.query(
"INSERT INTO categories(id, category, subcategory, cat_subcat) VALUES (%s, %s, %s, %s)",
(num, category, subcategory, cat_subcat))
def purge_lastlog(self, days):
with self as db:
return db.query(
......@@ -873,7 +846,6 @@ class MySQL(ObjectBase):
" WHERE timestamp < DATE_SUB(CURDATE(), INTERVAL %s DAY) AND last IS NULL",
(days,)).rowcount
def purge_events(self, days):
with self as db:
affected = 0
......@@ -891,7 +863,6 @@ class MySQL(ObjectBase):
return affected
def expose(read=1, write=0, debug=0):
def expose_deco(meth):
......@@ -913,10 +884,9 @@ class Server(ObjectBase):
self.auth = auth
self.handler = handler
def __str__(self):
return "%s(req=%s, auth=%s, handler=%s)" % (type(self).__name__, type(self.req).__name__, type(self.auth).__name__, type(self.handler).__name__)
return "%s(req=%s, auth=%s, handler=%s)" % (
type(self).__name__, type(self.req).__name__, type(self.auth).__name__, type(self.handler).__name__)
def sanitize_args(self, path, func, args, exclude=["self", "post"]):
# silently remove internal args, these should never be used
......@@ -937,7 +907,6 @@ class Server(ObjectBase):
return args
def wsgi_app(self, environ, start_response, exc_info=None):
path = environ.get("PATH_INFO", "").lstrip("/")
self.req.reset(env=environ, path=path)
......@@ -996,11 +965,9 @@ class Server(ObjectBase):
self.req.reset()
return [output]
__call__ = wsgi_app
def json_wrapper(method):
def meth_deco(self, post, **args):
......@@ -1008,7 +975,8 @@ def json_wrapper(method):
try:
events = json.loads(post) if post else None
except Exception as e:
raise self.req.error(message="Deserialization error.", error=400,
raise self.req.error(
message="Deserialization error.", error=400,
exc=sys.exc_info(), args=post, parser=str(e))
if events:
args["events"] = events
......@@ -1020,8 +988,7 @@ def json_wrapper(method):
# which could (although shouldn't) appear in handler code
output = json.dumps(result, default=lambda v: str(v))
except Exception as e:
raise self.req.error(message="Serialization error", error=500,
exc=sys.exc_info(), args=str(result))
raise self.req.error(message="Serialization error", error=500, exc=sys.exc_info(), args=str(result))
return [('Content-type', 'application/json')], output
......@@ -1034,7 +1001,8 @@ def json_wrapper(method):
class WardenHandler(ObjectBase):
def __init__(self, req, log, validator, db, auth,
def __init__(
self, req, log, validator, db, auth,
send_events_limit=500, get_events_limit=1000,
description=None):
......@@ -1046,13 +1014,11 @@ class WardenHandler(ObjectBase):
self.get_events_limit = get_events_limit
self.description = description
def __str__(self):
return "%s(req=%s, validator=%s, db=%s, send_events_limit=%s, get_events_limit=%s, description=\"%s\")" % (
type(self).__name__, type(self.req).__name__, type(self.validator).__name__, type(self.db).__name__,
self.get_events_limit, self.send_events_limit, self.description)
@expose(read=1, debug=1)
@json_wrapper
def getDebug(self):
......@@ -1076,7 +1042,6 @@ class WardenHandler(ObjectBase):
}
}
@expose(read=1)
@json_wrapper
def getInfo(self):
......@@ -1089,10 +1054,10 @@ class WardenHandler(ObjectBase):
info["description"] = self.description
return info
@expose(read=1)
@json_wrapper
def getEvents(self, id=None, count=None,
def getEvents(
self, id=None, count=None,
cat=None, nocat=None,
tag=None, notag=None,
group=None, nogroup=None):
......@@ -1139,7 +1104,6 @@ class WardenHandler(ObjectBase):
return res
def check_node(self, event, name):
try:
ev_id = event['Node'][0]['Name'].lower()
......@@ -1150,7 +1114,6 @@ class WardenHandler(ObjectBase):
return [{"error": 422, "message": "Node does not correspond with saving client"}]
return []
def add_event_nums(self, ilist, events, errlist):
for err in errlist:
err.setdefault("events", []).extend(ilist)
......@@ -1164,7 +1127,6 @@ class WardenHandler(ObjectBase):
ev_ids.append(id)
return errlist
@expose(write=1)
@json_wrapper
def sendEvents(self, events=[]):
......@@ -1173,10 +1135,8 @@ class WardenHandler(ObjectBase):
errs = []
if len(events) > self.send_events_limit:
errs.extend(
self.add_event_nums(range(self.send_events_limit, len(events)), events,
[{"error": 507, "message": "Too much events in one batch.",
"send_events_limit": self.send_events_limit}]))
errs.extend(self.add_event_nums(range(self.send_events_limit, len(events)), events, [
{"error": 507, "message": "Too much events in one batch.", "send_events_limit": self.send_events_limit}]))
saved = 0
events_tosend = []
......@@ -1194,14 +1154,19 @@ class WardenHandler(ObjectBase):
continue
if self.req.client.test and not 'Test' in event.get('Category', []):
errs.extend(self.add_event_nums([i], events, [{"error": 422,
errs.extend(
self.add_event_nums([i], events, [{
"error": 422,
"message": "You're allowed to send only messages, containing \"Test\" among categories.",
"categories": event.get('Category', [])}]))
continue
raw_event = json.dumps(event)
if len(raw_event) >= self.db.event_size_limit:
errs.extend(self.add_event_nums([i], events, [{"error": 413, "message": "Event too long (>%i B)" % self.db.event_size_limit}]))
errs.extend(
self.add_event_nums([i], events, [
{"error": 413, "message": "Event too long (>%i B)" % self.db.event_size_limit}
]))
continue
events_tosend.append(event)
......@@ -1222,7 +1187,6 @@ class WardenHandler(ObjectBase):
return {"saved": saved}
def read_ini(path):
c = ConfigParser.RawConfigParser()
res = c.read(path)
......@@ -1245,7 +1209,8 @@ def read_cfg(path):
conf = json.loads(stripcomments)
# Lowercase keys
conf = dict((sect.lower(), dict(
conf = dict((
sect.lower(), dict(
(subkey.lower(), val) for subkey, val in subsect.iteritems())
) for sect, subsect in conf.iteritems())
......@@ -1364,7 +1329,6 @@ def build_server(conf, section_order=section_order, section_def=section_def, par
objects = {} # Already initialized objects
# Functions for validation and conversion of config values
def facility(name):
return int(getattr(logging.handlers.SysLogHandler, "LOG_" + name.upper()))
......@@ -1385,7 +1349,6 @@ def build_server(conf, section_order=section_order, section_def=section_def, par
def obj(name):
return objects[name.lower()]
# Typedef dictionary
conv_dict = {
"facility": facility,
......@@ -1396,7 +1359,6 @@ def build_server(conf, section_order=section_order, section_def=section_def, par
"str": str
}
def init_obj(sect_name):
config = conf.get(sect_name, {})
sect_name = sect_name.lower()
......@@ -1469,7 +1431,6 @@ def build_server(conf, section_order=section_order, section_def=section_def, par
return objects["server"]
# Command line utilities
def check_config():
......@@ -1526,7 +1487,6 @@ def modify_client(**kwargs):
client = server.handler.db.get_clients(id)
return client and True or False
if kwargs["name"] is not None:
kwargs["name"] = kwargs["name"].lower()
if not isValidNSID(kwargs["name"]):
......@@ -1580,41 +1540,52 @@ def purge(days=30, lastlog=None, events=None):
def add_client_args(subargp, mod=False):
subargp.add_argument("--help", action="help", help="show this help message and exit")
if mod:
subargp.add_argument("-i", "--id", required=True, type=int,
subargp.add_argument(
"-i", "--id", required=True, type=int,
help="client id")
subargp.add_argument("-n", "--name", required=not mod,
subargp.add_argument(
"-n", "--name", required=not mod,
help="client name (in dotted reverse path notation)")
subargp.add_argument("-h", "--hostname", required=not mod,
subargp.add_argument(
"-h", "--hostname", required=not mod,
help="client FQDN hostname")
subargp.add_argument("-r", "--requestor", required=not mod,
subargp.add_argument(
"-r", "--requestor", required=not mod,
help="requestor email")
subargp.add_argument("-s", "--secret",
subargp.add_argument(
"-s", "--secret",
help="authentication token (use explicit empty string to disable)")
subargp.add_argument("--note",
subargp.add_argument(
"--note",
help="client freetext description")
reg_valid = subargp.add_mutually_exclusive_group(required=False)
reg_valid.add_argument("--valid", action="store_const", const=1, default=None,
reg_valid.add_argument(
"--valid", action="store_const", const=1, default=None,
help="valid client (default)")
reg_valid.add_argument("--novalid", action="store_const", const=0, dest="valid", default=None)
reg_read = subargp.add_mutually_exclusive_group(required=False)
reg_read.add_argument("--read", action="store_const", const=1, default=None,
reg_read.add_argument(
"--read", action="store_const", const=1, default=None,
help="client is allowed to read (default)")
reg_read.add_argument("--noread", action="store_const", const=0, dest="read", default=None)
reg_write = subargp.add_mutually_exclusive_group(required=False)
reg_write.add_argument("--nowrite", action="store_const", const=0, dest="write", default=None,
reg_write.add_argument(
"--nowrite", action="store_const", const=0, dest="write", default=None,
help="client is allowed to send (default - no)")
reg_write.add_argument("--write", action="store_const", const=1, default=None)
reg_debug = subargp.add_mutually_exclusive_group(required=False)
reg_debug.add_argument("--nodebug", action="store_const", const=0, dest="debug", default=None,
reg_debug.add_argument(
"--nodebug", action="store_const", const=0, dest="debug", default=None,
help="client is allowed receive debug output (default - no)")
reg_debug.add_argument("--debug", action="store_const", const=1, default=None)
reg_test = subargp.add_mutually_exclusive_group(required=False)
reg_test.add_argument("--test", action="store_const", const=1, default=None,
reg_test.add_argument(
"--test", action="store_const", const=1, default=None,
help="client is yet in testing phase (default - yes)")
reg_test.add_argument("--notest", action="store_const", const=0, dest="test", default=None)
......@@ -1623,65 +1594,81 @@ def get_args():
import argparse
argp = argparse.ArgumentParser(
description="Warden server " + VERSION, add_help=False)
argp.add_argument("--help", action="help",
argp.add_argument(
"--help", action="help",
help="show this help message and exit")
argp.add_argument("-c", "--config",
argp.add_argument(
"-c", "--config",
help="path to configuration file")
subargp = argp.add_subparsers(title="commands")
subargp_check = subargp.add_parser("check", add_help=False,
subargp_check = subargp.add_parser(
"check", add_help=False,
description="Try to setup server based on configuration file.",
help="check configuration")
subargp_check.set_defaults(command=check_config)
subargp_check.add_argument("--help", action="help",
subargp_check.add_argument(
"--help", action="help",
help="show this help message and exit")
subargp_reg = subargp.add_parser("register", add_help=False,
subargp_reg = subargp.add_parser(
"register", add_help=False,
description="Add new client registration entry.",
help="register new client")
subargp_reg.set_defaults(command=register_client)
add_client_args(subargp_reg)
subargp_mod = subargp.add_parser("modify", add_help=False,
subargp_mod = subargp.add_parser(
"modify", add_help=False,
description="Modify details of client registration entry.",
help="modify client registration")
subargp_mod.set_defaults(command=modify_client)
add_client_args(subargp_mod, mod=True)
subargp_list = subargp.add_parser("list", add_help=False,
subargp_list = subargp.add_parser(
"list", add_help=False,
description="List details of client registration entries.",
help="list registered clients")
subargp_list.set_defaults(command=list_clients)
subargp_list.add_argument("--help", action="help",
subargp_list.add_argument(
"--help", action="help",
help="show this help message and exit")
subargp_list.add_argument("--id", action="store", type=int,
subargp_list.add_argument(
"--id", action="store", type=int,
help="client id", default=None)
subargp_purge = subargp.add_parser("purge", add_help=False,
description=
subargp_purge = subargp.add_parser(
"purge", add_help=False,
description=(
"Purge old events or lastlog records."
" Note that lastlog purge retains at least one newest record for each"
" client, even if it is more than number of 'days' old.",
" client, even if it is more than number of 'days' old."),
help="purge old events or lastlog records")
subargp_purge.set_defaults(command=purge)
subargp_purge.add_argument("--help", action="help",
subargp_purge.add_argument(
"--help", action="help",
help="show this help message and exit")
subargp_purge.add_argument("-l", "--lastlog", action="store_true", dest="lastlog", default=None,
subargp_purge.add_argument(
"-l", "--lastlog", action="store_true", dest="lastlog", default=None,
help="purge lastlog records")
subargp_purge.add_argument("-e", "--events", action="store_true", dest="events", default=None,
subargp_purge.add_argument(
"-e", "--events", action="store_true", dest="events", default=None,
help="purge events")
subargp_purge.add_argument("-d", "--days", action="store", dest="days", type=int, default=30,
subargp_purge.add_argument(
"-d", "--days", action="store", dest="days", type=int, default=30,
help="records older than 'days' back from today will get purged")
subargp_loadmaps = subargp.add_parser("loadmaps", add_help=False,
description=
subargp_loadmaps = subargp.add_parser(
"loadmaps", add_help=False,
description=(
"Load 'categories' and 'tags' table from 'catmap_mysql.json' and 'tagmap_mysql.json'."
" Note that this is NOT needed for server at all, load them into db at will,"
" should you need to run your own specific SQL queries on data directly."
" Note also that previous content of both tables will be lost.",
" Note also that previous content of both tables will be lost."),
help="load catmap and tagmap into db")
subargp_loadmaps.set_defaults(command=load_maps)
subargp_loadmaps.add_argument("--help", action="help",
subargp_loadmaps.add_argument(
"--help", action="help",
help="show this help message and exit")
return argp.parse_args()
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment