From 616788834c4e4654b5ef0b114126cc9586efceb1 Mon Sep 17 00:00:00 2001 From: Frank Brehm Date: Tue, 23 Oct 2018 17:07:07 +0200 Subject: [PATCH] Adding possibility for defining a configuration file --- etc/create-vmware-template.ini.default | 2 + lib/cr_vmware_tpl/app.py | 89 ++++++++++++++++++++------ lib/cr_vmware_tpl/config.py | 13 ++-- python_fb_tools | 2 +- 4 files changed, 76 insertions(+), 30 deletions(-) diff --git a/etc/create-vmware-template.ini.default b/etc/create-vmware-template.ini.default index a2de4a9..b7387c5 100644 --- a/etc/create-vmware-template.ini.default +++ b/etc/create-vmware-template.ini.default @@ -10,6 +10,8 @@ ;dc = vmcc +;cluster = vmcc-l105-01 + ;folder = templates [Template] diff --git a/lib/cr_vmware_tpl/app.py b/lib/cr_vmware_tpl/app.py index 51c14ae..cd3286b 100644 --- a/lib/cr_vmware_tpl/app.py +++ b/lib/cr_vmware_tpl/app.py @@ -18,6 +18,7 @@ import textwrap import argparse import getpass import argparse +import pathlib # Third party modules @@ -25,10 +26,12 @@ import argparse from . import __version__ as GLOBAL_VERSION import fb_tools + +from fb_tools.common import pp, caller_search_path + from fb_tools.app import BaseApplication -from fb_tools.errors import FbAppError, ExpectedHandlerError, CommandNotFoundError -from fb_tools.common import caller_search_path +from fb_tools.errors import FbAppError, ExpectedHandlerError, CommandNotFoundError from .config import CrTplConfiguration @@ -69,6 +72,33 @@ class NrTemplatesOptionAction(argparse.Action): setattr(namespace, self.dest, values) +# ============================================================================= +class CfgFileOptionAction(argparse.Action): + + # ------------------------------------------------------------------------- + def __init__(self, option_strings, *args, **kwargs): + + super(CfgFileOptionAction, self).__init__( + option_strings=option_strings, *args, **kwargs) + + # ------------------------------------------------------------------------- + def __call__(self, parser, namespace, values, option_string=None): + + if values is None: + setattr(namespace, self.dest, None) + return + + path = pathlib.Path(values) + if not path.exists(): + msg = "File {!r} does not exists.".format(values) + raise argparse.ArgumentError(self, msg) + if not path.is_file(): + msg = "File {!r} is not a regular file.".format(values) + raise argparse.ArgumentError(self, msg) + + setattr(namespace, self.dest, path.resolve()) + + # ============================================================================= class CrTplApplication(BaseApplication): """ @@ -89,6 +119,7 @@ class CrTplApplication(BaseApplication): which can be used to spawn different virtual machines. """).strip() + self._cfg_file = None self.config = None super(CrTplApplication, self).__init__( @@ -102,6 +133,12 @@ class CrTplApplication(BaseApplication): self.initialized = True + # ------------------------------------------------------------------------- + @property + def cfg_file(self): + """Configuration file.""" + return self._cfg_file + # ------------------------------------------------------------------------- def as_dict(self, short=True): """ @@ -115,6 +152,7 @@ class CrTplApplication(BaseApplication): """ res = super(CrTplApplication, self).as_dict(short=short) + res['cfg_file'] = self.cfg_file return res @@ -187,20 +225,27 @@ class CrTplApplication(BaseApplication): self.init_logging() + self.perform_arg_parser() + self.config = CrTplConfiguration( - appname=self.appname, verbose=self.verbose, base_dir=self.base_dir) + appname=self.appname, verbose=self.verbose, base_dir=self.base_dir, + config_file=self.cfg_file) + #self.config.config_file = self.cfg_file self.config.read() if self.config.verbose > self.verbose: self.verbose = self.config.verbose self.config.initialized = True - self.perform_arg_parser() + if self.verbose > 3: + LOG.debug("Read configuration:\n{}".format(pp(self.config.as_dict()))) + + self.perform_arg_parser_vmware() -# if not self.config.password: -# prompt = 'Enter password for host {h!r} and user {u!r}: '.format( -# h=self.config.vsphere_host, u=self.config.vsphere_user) -# self.config.password = getpass.getpass(prompt=prompt) + if not self.config.password: + prompt = 'Enter password for host {h!r} and user {u!r}: '.format( + h=self.config.vsphere_host, u=self.config.vsphere_user) + self.config.password = getpass.getpass(prompt=prompt) self.handler = CrTplHandler( appname=self.appname, verbose=self.verbose, base_dir=self.base_dir) @@ -222,11 +267,19 @@ class CrTplApplication(BaseApplication): super(CrTplApplication, self).init_arg_parser() + default_cfg_file = self.base_dir.joinpath('etc').joinpath(self.appname + '.ini') + self.arg_parser.add_argument( '-A', '--abort', dest='abort', action='store_true', help="Abort creation of VMWare template after successsful creation of template VM.", ) + self.arg_parser.add_argument( + '-c', '--config', '--config-file', dest='cfg_file', metavar='FILE', + action=CfgFileOptionAction, + help="Configuration file (default: {!r})".format(default_cfg_file) + ) + vmware_group = self.arg_parser.add_argument_group('VMWare options') vmware_group.add_argument( @@ -295,13 +348,17 @@ class CrTplApplication(BaseApplication): # ------------------------------------------------------------------------- def perform_arg_parser(self): + + if self.args.cfg_file: + self._cfg_file = self.args.cfg_file + + # ------------------------------------------------------------------------- + def perform_arg_parser_vmware(self): """ Public available method to execute some actions after parsing the command line parameters. """ - pass - if self.args.host: self.config.vsphere_host = self.args.host if self.args.port: @@ -320,17 +377,7 @@ class CrTplApplication(BaseApplication): self.config.template_name = self.args.template if self.args.number is not None: - v = self.args.number - if v < 1: - LOG.error(( - "Wrong number {} of templates to stay in templates folder, " - "must be greater than zero.").format(v)) - elif v >= 100: - LOG.error(( - "Wrong number {} of templates to stay in templates folder, " - "must be less than 100.").format(v)) - else: - self.config.max_nr_templates_stay = v + self.config.max_nr_templates_stay = self.args.number # ------------------------------------------------------------------------- def _run(self): diff --git a/lib/cr_vmware_tpl/config.py b/lib/cr_vmware_tpl/config.py index f2e2785..5c45de7 100644 --- a/lib/cr_vmware_tpl/config.py +++ b/lib/cr_vmware_tpl/config.py @@ -62,7 +62,7 @@ class CrTplConfiguration(BaseConfiguration): # ------------------------------------------------------------------------- def __init__( self, appname=None, verbose=0, version=__version__, base_dir=None, - initialized=False): + encoding=None, config_dir=None, config_file=None, initialized=False): self.vsphere_host = self.default_vsphere_host self.vsphere_port = self.default_vsphere_port @@ -84,11 +84,8 @@ class CrTplConfiguration(BaseConfiguration): self.excluded_datastores = [] super(CrTplConfiguration, self).__init__( - appname=appname, - verbose=verbose, - version=version, - base_dir=base_dir, - initialized=False, + appname=appname, verbose=verbose, version=version, base_dir=base_dir, + encoding=encoding, config_dir=config_dir, config_file=config_file, initialized=False, ) # Workaround, bis das Lesen der Config implementiert ist @@ -179,7 +176,7 @@ class CrTplConfiguration(BaseConfiguration): # ------------------------------------------------------------------------- def _eval_config_vsphere(self, config, section_name): - if self.verbose > 2: + if self.verbose > 1: LOG.debug("Checking config section {!r} ...".format(section_name)) re_excl_ds = re.compile(r'^\s*excluded?[-_]datastores?\s*$', re.IGNORECASE) @@ -233,7 +230,7 @@ class CrTplConfiguration(BaseConfiguration): # ------------------------------------------------------------------------- def _eval_config_template(self, config, section_name): - if self.verbose > 2: + if self.verbose > 1: LOG.debug("Checking config section {!r} ...".format(section_name)) for (key, value) in config.items(section_name): diff --git a/python_fb_tools b/python_fb_tools index 98a58ec..0aa1e1f 160000 --- a/python_fb_tools +++ b/python_fb_tools @@ -1 +1 @@ -Subproject commit 98a58ece2e8cb15223d584130e71ef59986cdf26 +Subproject commit 0aa1e1fd0335acf3f2447d1c00d413e93aced508 -- 2.39.5