From df5b7dcf1ebfc41b2ec3c647eb696f1d22fb19fb Mon Sep 17 00:00:00 2001 From: Michael Tremer Date: Mon, 28 Sep 2020 16:00:45 +0000 Subject: [PATCH] collectly-client: Move CLI code into CLI script Signed-off-by: Michael Tremer --- src/collecty-client | 175 ++++++++++++++++++++++++++++++++++++++- src/collecty/__init__.py | 4 +- src/collecty/client.py | 143 ++------------------------------ src/collecty/util.py | 19 +++++ 4 files changed, 199 insertions(+), 142 deletions(-) diff --git a/src/collecty-client b/src/collecty-client index c1e5d7b..d20709c 100755 --- a/src/collecty-client +++ b/src/collecty-client @@ -19,7 +19,176 @@ # # ############################################################################### -import collecty.client +import argparse +import collecty +import os +import sys -client = collecty.client.CollectyClient() -client.run_cli() +from collecty.i18n import _ + +class CLI(object): + def parse_cli(self): + parser = argparse.ArgumentParser( + description=_("Collecty Client") + ) + subparsers = parser.add_subparsers(help="sub-command help") + + # generate-graph + parser_generate_graph = subparsers.add_parser( + "generate-graph", help=_("Generate a graph image"), + ) + parser_generate_graph.add_argument( + "--filename", help=_("filename"), required=True, + ) + parser_generate_graph.add_argument( + "--format", help=_("image format"), + ) + parser_generate_graph.add_argument( + "--interval", help=_("interval"), + ) + parser_generate_graph.add_argument( + "--object", help=_("Object identifier"), default="default", + ) + parser_generate_graph.add_argument( + "--template", help=_("The graph template identifier"), required=True, + ) + parser_generate_graph.add_argument( + "--timezone", help=_("Generate the graph with timestamps plotted for the given timezone"), + default=os.environ.get("TZ", "UTC"), + ) + parser_generate_graph.add_argument( + "--locale", help=_("Generate the graph with this locale"), + default=os.environ.get("LANG", "en_GB.utf8"), + ) + # Dimensions + parser_generate_graph.add_argument( + "--height", type=int, default=0, help=_("Height of the generated image"), + ) + parser_generate_graph.add_argument( + "--width", type=int, default=0, help=_("Width of the generated image"), + ) + parser_generate_graph.set_defaults(func=self._generate_graph) + + # last-update + parser_last_update = subparsers.add_parser( + "last-update", help=_("Fetch the last dataset in the database"), + ) + parser_last_update.add_argument( + "--template", help=_("The graph template identifier"), required=True, + ) + parser_last_update.add_argument( + "--object", help=_("Object identifier"), default="default", + ) + parser_last_update.set_defaults(func=self._last_update) + + # list-templates + parser_list_templates = subparsers.add_parser( + "list-templates", help=_("Lists all graph templates"), + ) + parser_list_templates.set_defaults(func=self._list_templates) + + # backup + backup = subparsers.add_parser( + "backup", help=_("Backup all RRD data"), + ) + backup.add_argument( + "filename", nargs="?", help=_("Filename"), + ) + backup.set_defaults(func=self._backup) + + # version + parser_version = subparsers.add_parser( + "version", help=_("Show version"), + ) + parser_version.set_defaults(func=self._version) + + args = parser.parse_args() + + # Print usage if no action was given + if not "func" in args: + parser.print_usage() + sys.exit(2) + + return args + + def run(self): + # Parse command line arguments + args = self.parse_cli() + + # Initialise client + self.client = collecty.Collecty() + + # Call function + ret = args.func(args) + + # Return with exit code + if ret: + sys.exit(ret) + + # Otherwise just exit + sys.exit(0) + + def _backup(self, args): + print(_("Backing up...")) + + self.client.backup(args.filename) + + def _generate_graph(self, args): + kwargs = { + "format" : args.format or collecty.util.guess_format(args.filename), + "object_id" : args.object, + "locale" : args.locale, + "timezone" : args.timezone, + } + + if args.height or args.width: + kwargs.update({ + "height" : args.height or 0, + "width" : args.width or 0, + }) + + if args.interval: + kwargs["interval"] = args.interval + + # Generate the graph image + graph = self.client.generate_graph(args.template, **kwargs) + + # Add some useful information + info = self.client.graph_info(args.template, **kwargs) + if info: + graph.update(info) + + # Write file to disk + with open(args.filename, "wb") as f: + f.write(graph["image"]) + + print(_("Title : %(title)s (%(template)s - %(object_id)s)") % graph) + print(_("Image size : %(image_width)sx%(image_height)spx") % graph) + + def _last_update(self, args): + last_update = self.client.last_update(args.template, object_id=args.object) + + print(_("Last update: %s") % last_update.get("timestamp")) + + dataset = last_update.get("dataset") + for k, v in dataset.items(): + print("%16s = %s" % (k, v)) + + def _list_templates(self, args): + templates = self.client.list_templates() + + for t in sorted(templates): + print(t) + + def _version(self, args): + version = self.client.version() + + print(version) + + +def main(): + # Run the command line interface + c = CLI() + c.run() + +main() diff --git a/src/collecty/__init__.py b/src/collecty/__init__.py index 55492b2..01788a7 100644 --- a/src/collecty/__init__.py +++ b/src/collecty/__init__.py @@ -22,4 +22,6 @@ # Initialize logging from . import logger -from .client import CollectyClient +from .client import CollectyClient as Collecty + +from . import util diff --git a/src/collecty/client.py b/src/collecty/client.py index cee5bd8..e9f5d7d 100644 --- a/src/collecty/client.py +++ b/src/collecty/client.py @@ -44,11 +44,6 @@ class CollectyClient(object): """ self.proxy.Backup(filename) - def backup_cli(self, ns): - print(_("Backing up...")) - - self.backup(ns.filename) - def last_update(self, template_name, **kwargs): last_update = self.proxy.LastUpdate(template_name, kwargs) @@ -57,26 +52,11 @@ class CollectyClient(object): return last_update - def last_update_cli(self, ns): - last_update = self.last_update(ns.template, object_id=ns.object) - - print(_("Last update: %s") % last_update.get("timestamp")) - - dataset = last_update.get("dataset") - for k, v in dataset.items(): - print("%16s = %s" % (k, v)) - def list_templates(self): templates = self.proxy.ListTemplates() return ["%s" % t for t in templates] - def list_templates_cli(self, ns): - templates = self.list_templates() - - for t in sorted(templates): - print(t) - def graph_info(self, template_name, **kwargs): graph_info = self.proxy.GraphInfo(template_name, kwargs, signature="sa{sv}") @@ -93,121 +73,8 @@ class CollectyClient(object): return graph - def generate_graph_cli(self, ns): - kwargs = { - "format" : ns.format or self._guess_format(ns.filename), - "object_id" : ns.object, - } - - if ns.height or ns.width: - kwargs.update({ - "height" : ns.height or 0, - "width" : ns.width or 0, - }) - - if ns.interval: - kwargs["interval"] = ns.interval - - kwargs.update({ - "locale" : ns.locale, - "timezone" : ns.timezone, - }) - - # Generate the graph image - graph = self.generate_graph(ns.template, **kwargs) - - # Add some useful information - info = self.graph_info(ns.template, **kwargs) - if info: - graph.update(info) - - # Write file to disk - with open(ns.filename, "wb") as f: - f.write(graph["image"]) - - print(_("Title : %(title)s (%(template)s - %(object_id)s)") % graph) - print(_("Image size : %(image_width)sx%(image_height)spx") % graph) - - def _guess_format(self, filename): - parts = filename.split(".") - - if parts: - # The extension is the last part - extension = parts[-1] - - # Image formats are all uppercase - extension = extension.upper() - - if extension in SUPPORTED_IMAGE_FORMATS: - return extension - - # Otherwise fall back to the default format - return DEFAULT_IMAGE_FORMAT - - def version_cli(self, args): - daemon_version = self.proxy.Version() - - print(_("collecty %s running on Python %s") % \ - (COLLECTY_VERSION, platform.python_version())) - - if not COLLECTY_VERSION == daemon_version: - print(_("daemon %s") % daemon_version) - - def parse_cli(self, args): - parser = argparse.ArgumentParser(prog="collecty-client") - subparsers = parser.add_subparsers(help="sub-command help") - - # generate-graph - parser_generate_graph = subparsers.add_parser("generate-graph", - help=_("Generate a graph image")) - parser_generate_graph.set_defaults(func=self.generate_graph_cli) - parser_generate_graph.add_argument("--filename", - help=_("filename"), required=True) - parser_generate_graph.add_argument("--format", help=_("image format")) - parser_generate_graph.add_argument("--interval", help=_("interval")) - parser_generate_graph.add_argument("--object", - help=_("Object identifier"), default="default") - parser_generate_graph.add_argument("--template", - help=_("The graph template identifier"), required=True) - parser_generate_graph.add_argument("--timezone", default=os.environ.get("TZ", "UTC"), - help=_("Generate the graph with timestamps plotted for the given timezone")) - parser_generate_graph.add_argument("--locale", default=os.environ.get("LANG", "en_GB.utf8"), - help=_("Generate the graph with this locale")) - - # Dimensions - parser_generate_graph.add_argument("--height", type=int, default=0, - help=_("Height of the generated image")) - parser_generate_graph.add_argument("--width", type=int, default=0, - help=_("Width of the generated image")) - - # last-update - parser_last_update = subparsers.add_parser("last-update", - help=_("Fetch the last dataset in the database")) - parser_last_update.add_argument("--template", - help=_("The graph template identifier"), required=True) - parser_last_update.add_argument("--object", - help=_("Object identifier"), default="default") - parser_last_update.set_defaults(func=self.last_update_cli) - - # list-templates - parser_list_templates = subparsers.add_parser("list-templates", - help=_("Lists all graph templates")) - parser_list_templates.set_defaults(func=self.list_templates_cli) - - # backup - backup = subparsers.add_parser("backup", - help=_("Backup all RRD data"), - ) - backup.add_argument("filename", nargs="?") - backup.set_defaults(func=self.backup_cli) - - # version - parser_version = subparsers.add_parser("version", help=_("Show version")) - parser_version.set_defaults(func=self.version_cli) - - return parser.parse_args(args) - - def run_cli(self, args=None): - args = self.parse_cli(args or sys.argv[1:]) - - return args.func(args) + def version(self): + """ + Returns the version of the daemon + """ + return self.proxy.Version() diff --git a/src/collecty/util.py b/src/collecty/util.py index e9921f8..ecb39b5 100644 --- a/src/collecty/util.py +++ b/src/collecty/util.py @@ -47,6 +47,25 @@ def make_interval(interval): except KeyError: return "end-%s" % interval +def guess_format(filename): + """ + Returns the best format by filename extension + """ + parts = filename.split(".") + + if parts: + # The extension is the last part + extension = parts[-1] + + # Image formats are all uppercase + extension = extension.upper() + + if extension in SUPPORTED_IMAGE_FORMATS: + return extension + + # Otherwise fall back to the default format + return DEFAULT_IMAGE_FORMAT + class ProcNetSnmpParser(object): """ This class parses /proc/net/snmp{,6} and allows -- 2.47.2