import copy
import pipes
import subprocess
+import smtplib
+from email.message import EmailMessage
# Third party modules
import yaml
self.ignore_projects = []
self.error_data = []
+ self.smtp_server = 'smtp.pixelpark.com'
+ self.smtp_port = 25
self.default_parent_dir = '/www/data'
self.default_email = DEFAULT_EMAIL
if 'default_email' in config and config['default_email']:
self.default_email = config['default_email']
+ if 'smtp_server' in config and config['smtp_server'].strip():
+ self.smtp_server = config['smtp_server'].strip()
+
+ if 'smtp_port' in config and config['smtp_port']:
+ msg = "Invalid port {p!r} for SMTP in {f!r} found.".format(
+ p=config['smtp_port'], f=yaml_file)
+ try:
+ port = int(config['smtp_port'])
+ if port > 0 and port < 2**16:
+ self.smtp_port = port
+ else:
+ self.error_data.append(msg)
+ except ValueError:
+ self.error_data.append(msg)
+
if 'default_parent_dir' in config and config['default_parent_dir']:
pdir = config['default_parent_dir']
if os.path.isabs(pdir):
# create formatter
format_str = ''
- if self.verbose > 1:
+ if 'REQUEST_METHOD' in os.environ or self.verbose > 1:
format_str = '[%(asctime)s]: '
format_str += self.appname + ': '
if self.verbose:
'user_name': 'Frank Brehm'}
"""
- #print("Content-Type: text/plain;charset=utf-8")
- #print()
- #sys.stdout.buffer.write(to_bytes("Python CGI läuft.\n"))
- #sys.stdout.flush()
self.print_out("Content-Type: text/plain;charset=utf-8\n")
self.print_out("Python CGI läuft.\n")
- LOG.info("Starting ...")
LOG.debug("Base directory: {!r}".format(self.base_dir))
self.data = sys.stdin.read()
msg = "Got a {n} reading input data as JSON: {e}".format(n=e.__class__.__name__, e=e)
msg += "\nInput data: {!r}".format(self.data)
LOG.error(msg)
- error_data.append(msg)
+ self.error_data.append(msg)
else:
LOG.debug("Got JSON data:\n{}".format(pp(self.json_data)))
except Exception as e:
msg = "Got a {n} performing the deploy: {e}".format(n=e.__class__.__name__, e=e)
msg += "\n\nTraceback:\n{}".format(traceback.format_exc())
- error_data.append(msg)
+ self.error_data.append(msg)
LOG.error(msg)
finally:
+ if self.full_name:
+ self.send_error_msgs(self.full_name)
+ else:
+ self.send_error_msgs()
LOG.info("Finished.")
sys.exit(0)
+ # -------------------------------------------------------------------------
+ def send_error_msgs(self, project='undefined'):
+
+ if not self.error_data:
+ return
+
+ msg = EmailMessage()
+
+ s = ''
+ if len(self.error_data) > 1:
+ s = 's'
+
+ body = 'Error{s} while processing {p!r} project:\n\n'.format(
+ s=s, p=project)
+ body += '\n\n'.join(self.error_data)
+ body += '\n\nCheers\nPuppetmaster'
+ msg.set_content(body)
+ msg.set_charset('utf-8')
+
+ msg['Subject'] = 'Puppetmaster deploy error{s} for project {p!r}'.format(
+ s=s, p=project)
+ msg['From'] = self.sender_address
+ to_addresses = ''
+ if self.mail_to_addresses:
+ to_addresses = ', '.join(self.mail_to_addresses)
+ else:
+ to_addresses = self.default_email
+ msg['To'] = to_addresses
+ if self.mail_cc_addresses:
+ msg['CC'] = ', '.join(self.mail_cc_addresses)
+
+ msg['X-Mailer'] = "Puppetmaster deploy script v.{}".format(__version__)
+
+ if self.verbose:
+ LOG.info("Sending the following mail to {r!r} via {s}:{p}:\n{m}".format(
+ r=to_addresses, m=msg.as_string(unixfrom=True),
+ s=self.smtp_server, p=self.smtp_port))
+ else:
+ LOG.info("Sending a mail to {r!r} via {s}:{p}:\n{e}".format(
+ r=to_addresses, e=pp(self.error_data),
+ s=self.smtp_server, p=self.smtp_port))
+
+ server = smtplib.SMTP(self.smtp_server, self.smtp_port)
+ if 'REQUEST_METHOD' not in os.environ:
+ if self.verbose > 2:
+ server.set_debuglevel(2)
+ elif self.verbose > 1:
+ server.set_debuglevel(1)
+ server.starttls()
+ result = server.send_message(msg)
+ server.quit()
+
+ if not result.keys():
+ LOG.debug("Susseccful sent message to {r!r} via {s}:{p}.".format(
+ r=to_addresses, s=self.smtp_server, p=self.smtp_port))
+ else:
+ LOG.error((
+ "Errors on sending error message for project "
+ "{pr!r} to {r!r} via {s}:{p}:\n{e}").format(
+ r=to_addresses, s=self.smtp_server, p=self.smtp_port,
+ pr=project, e=pp(result)))
+
+ return
+
# -------------------------------------------------------------------------
def perform(self):
'''Performing the stuff...'''
if self.special_chars_re.search(self.name):
msg = "Project {!r}: ".format(self.full_name) + self.mail_bodies['special_chars']
LOG.error(msg)
- error_data.append(msg)
+ self.error_data.append(msg)
return True
committers = []
return self.deploy(cfg)
msg = "Could not find a definition for project {!r}.".format(self.full_name)
- error_data.append(msg)
+ self.error_data.append(msg)
LOG.error(msg)
return True
if not os.access(parent_dir, os.F_OK):
msg = "Parent directory {!r} for Hiera does not exists.".format(parent_dir)
LOG.error(msg)
- error_data.append(msg)
+ self.error_data.append(msg)
return True
if not os.path.isdir(parent_dir):
msg = "Path of parent directory {!r} for Hiera is not a directory.".format(parent_dir)
LOG.error(msg)
- error_data.append(msg)
+ self.error_data.append(msg)
return True
return self.ensure_workingdir(parent_dir, workdir)
msg = "Parent directory {d!r} of project {p!r} does not exists.".format(
d=parent_dir, p=full_name)
LOG.error(msg)
- error_data.append(msg)
+ self.error_data.append(msg)
return True
if not os.path.isdir(parent_dir):
msg = ("Path for parent directory {d!r} for project {p!r} "
"is not a directory.").format(d=parent_dir, p=full_name)
LOG.error(msg)
- error_data.append(msg)
+ self.error_data.append(msg)
return True
env_branch = 'undefined'
msg = "Branch directory {d!r} of project {p!r} does not exists.".format(
d=full_path_branch, p=full_name)
LOG.error(msg)
- error_data.append(msg)
+ self.error_data.append(msg)
return True
modules_dir = os.path.join(full_path_branch, 'modules')
msg = "Modules directory {d!r} of project {p!r} does not exists.".format(
d=modules_dir, p=full_name)
LOG.error(msg)
- error_data.append(msg)
+ self.error_data.append(msg)
return True
branc2clone = None
msg = "Parent directory {d!r} of project {p!r} does not exists.".format(
d=parent_dir, p=full_name)
LOG.error(msg)
- error_data.append(msg)
+ self.error_data.append(msg)
return True
if not os.path.isdir(parent_dir):
"Path for parent directory {d!r} for project {p!r} "
"is not a directory.").format(d=parent_dir, p=full_name)
LOG.error(msg)
- error_data.append(msg)
+ self.error_data.append(msg)
return True
return self.ensure_workingdir(parent_dir, workdir, branch)
if stderrdata:
msg = "Error messages on '{c}':\n{e}".format(c=cmd_str, e=to_str(stderrdata))
LOG.warn(msg)
- error_data.append(msg)
+ self.error_data.append(msg)
self.print_out(msg)
finally:
os.chdir(cur_dir)