Есть необходимость в сравнении несколько конфигурационных файлов из двух бранчей.
Скрипт загружает их из репозитория с помощью модуля pysvn, сохраняет под различными именами и с помощью модуля difflib выполняет сравнение.
Потом — создаётся репорт, в который включены различающиеся строки, и отправляется на почту.
Сам скрипт:
#!/usr/bin/env python
import sys
import os
import re
import difflib
import pysvn
import smtplib
import mimetypes
import email
import email.mime.application
import logging
import time
if len(sys.argv) < 2:
print('Usage: %s [old brahcn number] [new branch number]nExample:n%s 4.8 4.12' % (__file__, __file__))
sys.exit(1)
LOGPATH = '/var/log/configchecks.log'
BRANCH_NUM_OLD_CONF = sys.argv[1]
BRANCH_NUM_NEW_CONF = sys.argv[2]
CONFIGS = ('services.PROD.properties', 'services.properties', 'dao.properties', 'dao.PROD.properties')
URL = 'https://www.domain.com/svn/repos/%s.x/resources/%s'
REPORT = []
logging.basicConfig(format = '%(filename)s - %(levelname)-3s [%(asctime)s] %(message)s ', filename=LOGPATH, level=logging.INFO)
def svn_export(url_old, url_new, local_old, local_new, file):
client = pysvn.Client()
try:
logging.info('Extracting file %s...' % file)
client.export(url_old, local_old)
client.export(url_new, local_new)
for i in (local_old, local_new):
if os.path.isfile(i):
logging.info('File %s saved.' % i)
else:
logging.info("ERROR: can't find file %s." % i)
except pysvn._pysvn.ClientError as e:
logging.info('ERROR: %s' % e)
def diff_configs(local_old, local_new, file):
logging.info('Checking lines...')
local_old = open(local_old, 'r').readlines()
local_new = open(local_new, 'r').readlines()
d = difflib.Differ()
diff = difflib.ndiff(local_old, local_new)
num = 1
for line in diff:
if not re.match('^.{0,3}#', line):
if re.search('^-', line):
logging.debug('File %s in line %d: %s' % (file, num, line))
REPORT.append('File %s in line %d: %s' % (file, num, line))
num += 1
def runall(old_branch, new_branch):
for file in CONFIGS:
local_old = ('%s_%s' % (file, old_branch))
url_old = (URL % (old_branch, file))
local_new = ('%s_%s' % (file, new_branch))
url_new = (URL % (new_branch, file))
svn_export(url_old, url_new, local_old, local_new, file)
diff_configs(local_old, local_new, file)
def mail(old_branch, new_branch, report, date):
sender = '[email protected]'
to = ['[email protected]', '[email protected]', '[email protected]']
msg = email.mime.Multipart.MIMEMultipart()
msg['Subject'] = ('Configs checks for branches %s and %s' % (old_branch, new_branch))
msg['From'] = 'Configuration manager <[email protected]>'
msg['To'] = 'APP team <[email protected]>'
body = email.mime.Text.MIMEText("""
Report created %s.
%s
""" % (date, ('n'.join(report))))
msg.attach(body)
logging.info('Preparing email.')
smtpconnect = smtplib.SMTP('smtp.domain.com:25')
# smtpconnect.set_debuglevel(1)
smtpconnect.sendmail(sender, to, msg.as_string())
smtpconnect.quit()
logging.info('Mail sent.')
if __name__ == "__main__":
logging.info('Starting extract and compare files for branches %s and %s at %s.' % (BRANCH_NUM_OLD_CONF, BRANCH_NUM_NEW_CONF, (time.strftime('%Y-%m-%d-%H:%M'))))
runall(BRANCH_NUM_OLD_CONF, BRANCH_NUM_NEW_CONF)
mail(BRANCH_NUM_OLD_CONF, BRANCH_NUM_NEW_CONF, REPORT, (time.strftime('%Y-%m-%d-%H:%M')))
Запуск:
$ ./svn_1.py 4.8 14.12
Лог:
svn_1.py - INFO [2014-11-20 16:02:34,298] Starting extract and compare files for branches 4.8 and 14.12 at 2014-11-20-16:02. svn_1.py - INFO [2014-11-20 16:02:34,301] Extracting file services.PROD.properties... svn_1.py - INFO [2014-11-20 16:02:43,135] File services.PROD.properties_4.8 saved. svn_1.py - INFO [2014-11-20 16:02:43,135] File services.PROD.properties_14.12 saved. svn_1.py - INFO [2014-11-20 16:02:43,136] Checking lines... svn_1.py - INFO [2014-11-20 16:02:43,141] Extracting file services.properties... svn_1.py - INFO [2014-11-20 16:02:52,653] File services.properties_4.8 saved. svn_1.py - INFO [2014-11-20 16:02:52,654] File services.properties_14.12 saved. svn_1.py - INFO [2014-11-20 16:02:52,655] Checking lines... svn_1.py - INFO [2014-11-20 16:02:52,665] Extracting file dao.properties... svn_1.py - INFO [2014-11-20 16:03:03,625] File dao.properties_4.8 saved. svn_1.py - INFO [2014-11-20 16:03:03,626] File dao.properties_14.12 saved. svn_1.py - INFO [2014-11-20 16:03:03,626] Checking lines... svn_1.py - INFO [2014-11-20 16:03:03,671] Extracting file dao.PROD.properties... svn_1.py - INFO [2014-11-20 16:03:14,695] File dao.PROD.properties_4.8 saved. svn_1.py - INFO [2014-11-20 16:03:14,695] File dao.PROD.properties_14.12 saved. svn_1.py - INFO [2014-11-20 16:03:14,696] Checking lines... svn_1.py - INFO [2014-11-20 16:03:14,702] Preparing email. svn_1.py - INFO [2014-11-20 16:03:15,358] Mail sent.
И письмо:
Report:
File services.PROD.properties in line 29: —
File services.PROD.properties in line 30: — Url=https://domain.com/report
File services.properties in line 44: — Url=http://domain.com:11704/jj.dll
File dao.properties in line 66: —
File dao.properties in line 69: — jdbc.driverClassName=oracle.jdbc.driver.OracleDriver
File dao.properties in line 70: —
File dao.properties in line 73: — jdbc.url=jdbc:oracle:thin:@skynet.domain.com:1521:hh
File dao.properties in line 75: — jdbc.rf.username=user




