From 27030715cf7e26c95aa7f5c53995a38280e769e1 Mon Sep 17 00:00:00 2001 From: Frank Brehm Date: Wed, 25 Jan 2017 13:46:51 +0100 Subject: [PATCH] Adding configuration for deploy --- .gitignore | 3 + deploy-new.py | 6 +- deploy.yaml | 24 +++++++ lib/webhooks/deploy.py | 138 ++++++++++++++++++++++++++++++++++++++++- 4 files changed, 167 insertions(+), 4 deletions(-) create mode 100644 deploy.yaml diff --git a/.gitignore b/.gitignore index dd48430..57d02ee 100644 --- a/.gitignore +++ b/.gitignore @@ -18,3 +18,6 @@ \#*\# DEADJOE +deploy-old.py +test*.json + diff --git a/deploy-new.py b/deploy-new.py index 6ec3910..f701bd5 100755 --- a/deploy-new.py +++ b/deploy-new.py @@ -21,12 +21,12 @@ import webhooks from webhooks.deploy import WebhookDeployApp -MY_APPNAME = os.path.basename(sys.argv[0]) +MY_APPNAME = 'deploy' app = WebhookDeployApp(appname=MY_APPNAME) -#if app.verbose > 2: -# print("%s object:\n%s" % (app.__class__.__name__, app)) +if app.verbose > 2 and 'REQUEST_METHOD' not in os.environ: + print("%s object:\n%s" % (app.__class__.__name__, app)) app() diff --git a/deploy.yaml b/deploy.yaml new file mode 100644 index 0000000..b84e10a --- /dev/null +++ b/deploy.yaml @@ -0,0 +1,24 @@ +--- +verbose: 0 +log_dir: '/var/log/webhooks' +default_email: 'frank@brehm-online.com' +ignore_projects: +mail_cc_addresses: + - 'webmaster@pixelpark.com' + - 'frank.brehm@pixelpark.com' +sender_address: 'Puppetmaster ' +projects: + hiera: + namespace: 'puppet' + name: 'hiera' + parent_dir: '/www/data/puppet-hiera' + puppet_modules: + namespace: 'puppet' + parent_dir: '/www/data/puppet-environment' + +mail_bodies: + special_chars: "Received special characters in module name" + no_branch_dir: "Branch folder does not exist" + no_modules_dir: "Modules folder does not exist" + git_access_denied: "Access to remote repository was denied" + diff --git a/lib/webhooks/deploy.py b/lib/webhooks/deploy.py index 0aa1e4d..cc0edc0 100644 --- a/lib/webhooks/deploy.py +++ b/lib/webhooks/deploy.py @@ -15,6 +15,10 @@ import re import textwrap import datetime import json +import traceback + +# Third party modules +import yaml # Own modules import webhooks @@ -23,6 +27,9 @@ from webhooks.common import pp, to_bytes __version__ = webhooks.__version__ LOG = logging.getLogger(__name__) +DEFAULT_EMAIL = 'frank.brehm@pixelpark.com' +DEFAULT_SENDER = 'Puppetmaster <{}>'.format(DEFAULT_EMAIL) + # ============================================================================= class WebhookDeployApp(object): @@ -33,6 +40,13 @@ class WebhookDeployApp(object): cgi_bin_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '..')) base_dir = os.path.dirname(cgi_bin_dir) + mail_bodies = { + 'special_chars': "Received special characters in module name", + 'no_branch_dir': "Branch folder does not exist", + 'no_modules_dir': "Modules folder does not exist", + 'git_access_denied': "Access to remote repository was denied", + } + # ------------------------------------------------------------------------- def __init__(self, appname=None, version=__version__): """Constructor.""" @@ -68,8 +82,19 @@ class WebhookDeployApp(object): self.name = None self.full_name = None + self.ignore_projects = [] + + self.default_email = DEFAULT_EMAIL + self.mail_to_addresses = [] + self.mail_cc_addresses = [ + 'webmaster@pixelpark.com', + self.default_email, + ] + self.sender_address = DEFAULT_SENDER + self._log_directory = os.sep + os.path.join('var', 'log', 'webhooks') + self.read_config() self.init_logging() # ----------------------------------------------------------- @@ -117,6 +142,104 @@ class WebhookDeployApp(object): """The logfile of this application.""" return os.path.join(self.log_directory, self.appname + '.log') + # ------------------------------------------------------------------------- + def __str__(self): + """ + Typecasting function for translating object structure + into a string + + @return: structure as string + @rtype: str + """ + + return pp(self.as_dict()) + + # ------------------------------------------------------------------------- + def as_dict(self): + """ + Transforms the elements of the object into a dict + + @return: structure as dict + @rtype: dict + """ + + res = self.__dict__ + res = {} + for key in self.__dict__: + if key.startswith('_') and not key.startswith('__'): + continue + res[key] = self.__dict__[key] + res['__class_name__'] = self.__class__.__name__ + res['appname'] = self.appname + res['verbose'] = self.verbose + res['base_dir'] = self.base_dir + res['cgi_bin_dir'] = self.cgi_bin_dir + res['log_directory'] = self.log_directory + res['logfile'] = self.logfile + res['mail_bodies'] = self.mail_bodies + + return res + + # ------------------------------------------------------------------------- + def read_config(self): + """Reading configuration from different YAML files.""" + + yaml_files = [] + # ./deploy.yaml + yaml_files.append(os.path.join(self.base_dir, self.appname + '.yaml')) + # /etc/pixelpark/deploy.yaml + yaml_files.append(os.sep + os.path.join('etc', 'pixelpark', self.appname + '.yaml')) + + for yaml_file in yaml_files: + self.read_from_yaml(yaml_file) + + # ------------------------------------------------------------------------- + def read_from_yaml(self, yaml_file): + """Reading configuration from given YAML file.""" + + # LOG.debug("Trying to read config from {!r} ...".format(yaml_file)) + if not os.access(yaml_file, os.F_OK): + # LOG.debug("File {!r} does not exists.".format(yaml_file)) + return + # LOG.debug("Reading config from {!r} ...".format(yaml_file)) + config = {} + with open(yaml_file, 'rb') as fh: + config = yaml.load(fh.read()) + # LOG.debug("Read config:\n{}".format(pp(config))) + + if 'verbose' in config: + self.verbose = config['verbose'] + + if 'log_dir' in config and config['log_dir']: + self._log_directory = config['log_dir'] + + if 'default_email' in config and config['default_email']: + self.default_email = config['default_email'] + + if 'ignore_projects' in config: + if config['ignore_projects'] is None: + self.ignore_projects = [] + elif isinstance(config['ignore_projects'], str): + if config['ignore_projects']: + self.ignore_projects = [config['ignore_projects']] + elif isinstance(config['ignore_projects'], list): + self.ignore_projects = config['ignore_projects'] + + if 'mail_cc_addresses' in config: + if config['mail_cc_addresses'] is None: + self.mail_cc_addresses = [] + elif isinstance(config['mail_cc_addresses'], str): + if config['mail_cc_addresses']: + self.mail_cc_addresses = [config['mail_cc_addresses']] + else: + self.mail_cc_addresses = [] + elif isinstance(config['mail_cc_addresses'], list): + self.mail_cc_addresses = config['mail_cc_addresses'] + + if 'mail_bodies' in config and isinstance(config['mail_bodies'], list): + for key in config['mail_bodies'].keys(): + self.mail_bodies[key] = config['mail_bodies'][key] + # ------------------------------------------------------------------------- def init_logging(self): """ @@ -249,12 +372,25 @@ class WebhookDeployApp(object): LOG.debug("Got JSON data:\n{}".format(pp(self.json_data))) + try: + self.perform() + except Exception as e: + LOG.error("Got a {n} performing the deploy: {e}".format( + n=e.__class__.__name__, e=e)) + LOG.error("Traceback:\n{}".format(traceback.format_exc())) + + sys.exit(0) + + # ------------------------------------------------------------------------- + def perform(self): + '''Performing the stuff...''' + self.ref = self.json_data['ref'].split('/')[-1] self.namespace = self.json_data['project']['namespace'] self.name = self.json_data['project']['name'] self.full_name = self.json_data['project']['path_with_namespace'] - sys.exit(0) + return True # ============================================================================= -- 2.39.5