Exemple #1
0
 def setUp(self):
     self._cluster = "cluster"
     self._username = "******"
     self._password = "******"
     self._fakeConnection = FakeMysqlConnection()
     self._fakeCursor = FakeMysqlCursor()
     self._logPasswords = True
     echoAccessLevel = mysql_query_tool.QAL_ALL
     queryAccessLevel = mysql_query_tool.QAL_ALL
     mysql_query_tool.MySQLdb.connect = mock.MagicMock(
         return_value=self._fakeConnection)
     self._mysqlQueryTool = mysql_query_tool.MysqlQueryTool(
         self._cluster, self._username, self._password, echoAccessLevel,
         queryAccessLevel, self._logPasswords)
     self._mysqlQueryTool.getCursor = mock.MagicMock(
         return_value=self._fakeCursor)
def start(autoGrantConfig, echoOnly, logPasswords, destructive, passwordReset, revert, userList, groupList,
          clusterList):
    restoreName = ''
    restorePath = ''
    mysqlBackupTool = _getMysqlBackupTool(echoOnly, logPasswords)

    pruneBeforeDate = mysqlBackupTool.getPruneBeforeFromTimeDelta(
        datetime.timedelta(days=30))
    mysqlBackupTool.pruneBefore(pruneBeforeDate)
    if revert is not False:
        if revert is None:
            # default we use the last backup
            restoreName = mysqlBackupTool.getLastBackup()
        else:
            # default we use the last backup
            restoreName = revert
        backupDir = mysql_backup_tool.DEFAULT_BACKUP_DIR
        if restoreName is not None and 0 < len(restoreName):
            restorePath = os.path.join(backupDir, restoreName)
        if os.path.isdir(restorePath):
            revertUser = autoGrantConfig.getMysqlRevertUsername()
            revertPass = autoGrantConfig.getMysqlRevertPassword()
            mysqlBackupTool = _getMysqlBackupTool(echoOnly, logPasswords)
            for cluster in autoGrantConfig.getDbClusters():
                logger.info("reverting %s", cluster)
                echoAccessLevel = mysql_query_tool.QAL_ALL
                queryAccessLevel = mysql_query_tool.QAL_ALL
                if echoOnly:
                    queryAccessLevel = mysql_query_tool.QAL_NONE
                mysqlConn = mysql_query_tool.MysqlQueryTool(cluster, revertUser,
                                                            revertPass,
                                                            echoAccessLevel,
                                                            queryAccessLevel,
                                                            logPasswords)
                mysqlBackupTool.restoreFromMySQLDumpList(cluster, revertUser,
                                                         revertPass, restoreName,
                                                         [("mysql", "user")])
                mysqlConn.queryFlushPrivileges()
        else:
            logger.error("No backup was found under %s", backupDir)
    else:
        ldapUrl = autoGrantConfig.getLdapURL()
        ldapUsernameBase = autoGrantConfig.getLdapUsernameBase()
        ldapPassword = autoGrantConfig.getLdapPassword()
        ldapGroupDict = {}
        if ldapUrl is None or ldapUsernameBase is None or ldapPassword is None:
            logger.warning("missing one of ldapUrl:%s ldapUsernameBase:%s or ldapPassword:%s [%s]",
                           str(ldapUrl), str(ldapUsernameBase), str(ldapPassword),
                           "this will disable ldap integration")
        else:
            ldapQueryTool = ldap_query_tool.LdapQueryTool(ldapUrl,
                                                          ldapUsernameBase,
                                                          ldapPassword)
            ldapGroupDesc = autoGrantConfig.getLdapGroupDesc()
            ldapGroupDict = ldapQueryTool.queryLDAP(ldapGroupDesc)
        groupDict = makeGroupDict(autoGrantConfig, ldapGroupDict)
        if userList is not None:
            userList = userList.split(",")
        if groupList is not None:
            for group in groupList.split(","):
                if userList is None:
                    userList = []
                userList += groupDict[group]
        logger.debug("groupDict:\n"+pprint.pformat(groupDict))
        userDict = makeUserDict(autoGrantConfig, groupDict, userList)
        logger.debug("userDict:\n"+pprint.pformat(userDict))
        grantDict = makeGrantDict(autoGrantConfig, userDict, clusterList)
        logger.debug("grantDict:\n"+pprint.pformat(grantDict))
        grantAccess(autoGrantConfig, grantDict, echoOnly, logPasswords, destructive, passwordReset)
def grantAccess(autoGrantConfig, grantDict, echoOnly, logPasswords, destructive, passwordReset):
    """ This is the function that grants revokes and drops users
        Before adding any additional logica we should consider splitting
        this function to avoid it getting too unweildy
        NOTE: if destructive is False Revokes and Drop Users will be omitted
    """
    newUserDict = {}
    mysqlBackupTool = _getMysqlBackupTool(echoOnly, logPasswords)
    backupName = mysqlBackupTool.getCurrentTimeBackup()
    grantUser = autoGrantConfig.getMysqlGrantsUsername()
    grantPass = autoGrantConfig.getMysqlGrantsPassword()
    # determine access levels from echoOnly and destructive
    echoAccessLevel = mysql_query_tool.QAL_READ_WRITE
    if destructive or passwordReset:
        echoAccessLevel = mysql_query_tool.QAL_READ_WRITE_DELETE
    queryAccessLevel = echoAccessLevel
    if echoOnly:
        queryAccessLevel = mysql_query_tool.QAL_READ
    defaultCluster = grantDict.keys()[0]
    for cluster in grantDict.keys():
        mysqlBackupTool.performMySQLDumpList(cluster, grantUser, grantPass, backupName, [("mysql", "user")])
        logger.debug("backup saved")
        mysqlConn = mysql_query_tool.MysqlQueryTool(cluster, grantUser,
                                                    grantPass, echoAccessLevel,
                                                    queryAccessLevel, logPasswords)
        logger.debug("connection created")
        for userAtHost in grantDict[cluster].keys():
            logger.debug("working on %s", userAtHost)
            userPart, hostPart = (x.strip("'") for x in userAtHost.split('@'))
            mysqlConn.beginTransaction()
            passwordHash = mysqlConn.getPasswordHash(userPart, hostPart)
            userExists = (passwordHash is not None)
            if passwordReset and userExists:
                mysqlConn.dropUser(userAtHost)
                userExists = False
                passwordHash = None
            if userExists:
                logger.debug("CACHING PASSWORD HASH %s FOR %s ACCOUNT ON %s" % (passwordHash, userAtHost, cluster))
                updateMysqlUser(newUserDict, userAtHost, mysqlConn, passwordHash, None)
            else:
                logger.debug("NEED TO CREATE USER: %s", userAtHost)
                updateMysqlUser(newUserDict, userAtHost, mysqlConn, generateRandomPassword(), cluster)
            grantDeltaDict = {}
            try:
                for grant in grantDict[cluster][userAtHost]:
                    dbTable = grant['db_table']
                    privileges = grant['privileges']
                    grantDeltaDict = mysqlConn.getGrantDeltaDict(userAtHost, dbTable, privileges)
                    if 0 < len(grantDeltaDict['grants']):
                        mysqlConn.queryGrant(userAtHost,
                                             grantDeltaDict['grants'],
                                             dbTable)
                    if 0 < len(grantDeltaDict['revokes']):
                        mysqlConn.queryRevoke(userAtHost,
                                              grantDeltaDict['revokes'],
                                              dbTable)
                        mysqlConn.queryFlushPrivileges()
                mysqlConn.commitTransaction()
            except Exception as e:
                mysqlConn.rollbackTransaction()
                message = e.message + ": An exception occured when trying to grant:[%s] and revoke:[%s] to %s on %s" % (",".join(grantDeltaDict['grants']), ",".join(grantDeltaDict['revokes']), userAtHost, cluster)
                raise GrantException(message)
        if destructive and not passwordReset:
            # remove non defined users
            allMysqlUsers = mysqlConn.findAllUsers()
            usersToDrop = findUsersToDrop(autoGrantConfig, allMysqlUsers,
                                          grantDict[cluster].keys())
            for userToDropWithHost in usersToDrop:
                mysqlConn.dropUser(userToDropWithHost)
        mysqlConn.closeConnection()
    if echoOnly is False:
        sendEmailNotifications(autoGrantConfig, newUserDict, defaultCluster)