コード例 #1
0
def __warnIfLowSpace__():
    '''
	Called from checkRepositories().
	Checks if disk space below notification-size.
	'''
    pattern = re.compile(r'(\d+[M|G|T])')
    space = list(pattern.finditer(__getFreeDiskSpace__()))[0].group(
        1
    )  # get available disk-space to plain '(\d+[M|G|T])'-str (default return shape= 'X out of Y left on .')
    minSpace = config['notify']['warnIfDiskSpaceSmallerThan']
    pattern = re.compile(r'\d+[M|G|T]')
    if not pattern.finditer(minSpace):
        return __log__(
            'Invalid value for \'Warn if disk space smaller than\'-option.')

    # convert units if necessary
    # split into values- and units-part for easier processing
    values = [float(item[:-1]) for item in [space, minSpace]]
    units = [item[-1] for item in [space, minSpace]]

    # if unequal convert
    if units[0] != units[1]:
        order = ['M', 'G', 'T']
        exp = order.index(units[0]) - order.index(units[1])
        values[0] = values[0] * (1000**exp)

    # if available space below 'warnIfSpaceSmallerThan'-value, send warning log and mail if enabled
    if values[0] - values[1] < 0:
        return __log__(
            'WARNING: Available disk space is below \'warnIfSpaceSmallerThan\'-value.\nMail-notification returned with: \'{}\'.'
            .format(mailingNotification().manageMailing()))
コード例 #2
0
def checkRepositories():
    '''
	check if repos are healthty and update db-information
	'''
    # correct format of backupPath
    os.path.join(config['general']['backupPath'], '')

    # build path to repos based on given passwords
    repos = [
        os.path.join(config['general']['backupPath'], directory)
        for directory in os.listdir(os.path.join(gitProjectDir, 'passwords'))
    ]

    # check if each corresponding repo is valid
    status = [
        'no error'
        in __shell__('restic -r {} --password-file {} --no-cache check'.format(
            repo, os.path.join(gitProjectDir, 'passwords',
                               repo.split('/')[-1]))) for repo in repos
    ]

    # update repository data in db
    for j, repo in enumerate(repos):
        statusNum = [1 if stat else 0 for stat in [status[j]]][0]
        repoSpace = __shell__('du -sh {}'.format(repo)).split('\t')[0]
        try:
            repositories.objects.update_or_create(
                name=repo.split('/')[-1],
                absolPath=repo,
                diskSpace=repoSpace,
                lastUpdate=now(
                ),  #--> doing that initially (defined in index/models.py)
                health=statusNum)
        except:
            col = repositories.objects.get(absolPath=repo)
            col.name = repo.split('/')[-1]
            col.diskSpace = repoSpace
            col.lastUpdate = now(
            )  #--> doing that initially (defined in index/models.py)
            col.health = statusNum
            col.save()

    # execute shell "command after"-option
    __shell__(config['check']['executeCommandAfterCheck'])

    # call diskSpace-warning if necessary
    __warnIfLowSpace__()

    # if enabled, send notification
    # -------------------------------
    result = ''

    if __optionIsEnabled__(config['notify']['sendMailNotifications']):
        result = mailingNotification().manageMailing()

    # if result returned something, an error occurred
    if result:
        __log__(result)
        return render(request, 'checkOutput.html', {'output': result})
コード例 #3
0
ファイル: views.py プロジェクト: zoerbd/castic
def __getOverallSpace__(output, root):
    '''
	Return overall and available space of disk at mountpoint
	'''
    pattern = re.compile(
        r'\s+(\d+\.?\d+[A-Z]).+\s+(\d+\.?\d+[A-Z])\s+\d+%\s+{}?[\n]?$'.format(
            root))
    for line in output.split('\n'):
        result = [(match.group(1), match.group(2))
                  for match in pattern.finditer(line)]
        if result:
            return result[0]
    return (__log__(
        'Fatal error in __getOverallSpace__: couldn\'t determine available and overall space via regex.'
    ), '')
コード例 #4
0
    def doIntegrationAndSavePW(self):
        '''
		This function executes the previously rendered ansible-backend
		and returns the exit message.
		'''
        result = __shell__(
            'ansible-playbook ./integrate/ansible_rendered/setup.yml -e \"ansible_user={0}\" -e \"ansible_ssh_pass={1}\" -e \"ansible_become_pass={1}\"'
            .format(self.user, self.pw))
        passwdpath = os.path.join(gitProjectDir, 'passwords',
                                  ''.join(self.repoPath.split('/')[-1]))
        with open(passwdpath, 'w') as pwfile:
            pwfile.write(self.resticPW)
        if 'error' in result or 'Failed' in result or 'fatal' in result:
            __shell__('rm {}'.format(passwdpath))
            return __log__(
                'Error occurred while trying to integrate: {}'.format(result))
        return result
コード例 #5
0
ファイル: mailing.py プロジェクト: zoerbd/castic
    def __renderAndSendMail__(self):
        '''
		This method gets called by manageMailing().
		It authenticates the user at localhost or remote-end and
		tries to send the previously rendered mail.
		Returns nothing except an error occurred.
		'''
        # //// include these options
        user = self.config['smtpUsername']
        password = self.config['smtpPassword']
        # //// include these options

        content = """From: {}
To: {}
Subject: Castic: backup information\n
This is a generic mail from your castic server.
I am checking all made backups on certain time periods.\nAvailable disk-space on your backup volume: {}.\n\n""".format(
            self.config['mailFrom'], self.config['mailAddress'],
            __getFreeDiskSpace__())

        # check if all repos are healthy (fetch data from db). if not, append error message
        errors = [
            '{0} - FATAL ERROR: Error was detected in repository \'{1}\'.\nYou should check the repo and verify that the backup is done correctly.'
            .format(now(),
                    list(repositories.objects.values())[j])
            for j, health in enumerate(
                repositories.objects.values_list('health')) if health[0] != 1
        ]
        content += '\n'.join(errors)

        if not errors:
            content += 'All integrated servers were backuped successfully.\nEverything seems clean and healthy.\n\n'
        content += '\nRegards,\nyour backup-friend castic.'

        try:
            smtp = smtplib.SMTP(self.config['smtpServer'])
            if self.config['smtpUser'] and self.config['smtpPassword']:
                smtp.login(self.config['smtpUser'],
                           self.config['smtpPassword'])
            smtp.sendmail(self.config['mailFrom'],
                          self.config['mailAddress'].split(','), content)
        except Exception as err:
            return __log__(
                ' <--SMTP--> ERROR OCCURED WHILE TRYING TO SEND MAIL: {}\n'.
                format(err))
コード例 #6
0
ファイル: views.py プロジェクト: zoerbd/castic
def __getMountPoint__(output, root):
    '''
	Return mountpoint of backup-disk
	'''
    # iterate through possible mount-points by cutting /<something> after each iterat.
    mountPoint = []
    while not mountPoint:

        # update root by cutting last /<something>
        root = '/'.join(root.split('/')[:-1])

        if not root:
            root = '/'

        # check if mountpoint exists
        for line in output.split('\n'):
            pattern = re.compile(r'({}/?)$'.format(root))
            mountPoint = [match.group(1) for match in pattern.finditer(line)]
            if mountPoint:
                if len(mountPoint) != 1:
                    return __log__(
                        'Fatal error in index/views __getFreeDiskSpace__(): len of matched disk-mounts != 1.'
                    )
                return mountPoint[0]