同步多个gcp项目的防火墙

同步多个gcp项目的防火墙

同步多个gcp项目的防火墙,用于多个gcp项目(或账号)之间同步黑名单数据,需要使用基础库的数据库读写

from requests.packages import urllib3
import time, re
from google.cloud import compute _v1
from google. oauth2 import service_account
from BasicInterfaces import executeMysqlData
def listLessThan5kFirewallRule(credentials,projectId):
    client = compute _v1.FirewallsClient(credentials=credentials)
    firewallRuleList = client.list(project=projectId)
    query = "blocklist"
    for firewallName in firewallRuleList:
        if query in firewallName.name:
            if len(firewallName.source_ranges) != 5000:
                capacityFirewall = 5000 - Len(firewallName.source_ranges)
                return firewallName.name,capacityFirewall
            elif len(firewallName.source_ranges) == 2:
                try:
                    removeSourceIPToFirewallRule(credentials,projectId,firewallName.name,'224.1.1.132/32')
                except:
                    pass
            else:
                return None
def addSourceIPToFirewallRule(credentials,projectId,firewallRuleName,ipaddressForAdd):
    client = compute _v1.FirewallsClient(credentials=credentials)
    firewall = client.get(project=projectId,firewall=firewallRuleName)
    for i in ipaddressForAdd:
        firewall.source_ranges.append(i)
        try:
            operation = client.update(project=projectId, firewall=firewalLRuleName, firewall_resource=firewall)
            operation.result()
        except Exception as e:
            return str(e). split()[-1]
def removeSourceIPToFirewallRule(credentials,projectId,firewallRuleName,ipaddressForAdd):
    client = compute _v1.FirewallsClient(credentials=credentials)
    firewall = client.get(project=projectId, firewall=firewallRuleName)
    firewall.source_ranges.remove(ipaddressForAdd)
    operation = client.update(project=projectId, firewall=firewallRuleName, firewall_resource=firewall)
    operation. result()
def getResource0fFirewall(credentials,projectId,firewallRule):
    client = compute _v1.FirewallsClient(credentials=credentials)
    firewallRuleList = client.list(project=projectId)
    for firewallName in firewallRuleList:
        if firewallRule in firewallName.name:
            #print (firewallName.name)
            #time.sleep(30)
            #print (firewallName.source_ranges)
            return firewallName.source_ranges
def newFirewallPolicy(credentials,projectId, firewallRuleName, ipaddresses):
    client = compute _v1.FirewallsClient(credentials= credentials)
    firewall = {
        "denied": [{"I_p_ protocol": "all"}],
        "direction": "INGRESS",
        "name": firewallRuleName,
        "network": "global/networks/default",
        "priority": 999,
        "source_ranges": ipaddresses
        }
    try:
        client.insert(project=projectId, firewall_resource = firewall)
        return True
    except Exception as e:
        return (str(e).split()[-2] + " " + str(e).split()[-1])
projectsList = ["<projectname>"]
credentialsCST = service_account.Credentials.from_service_account_file('<xxx.json>')
for projectInfo in projectsList:
    print (f'开始处理{projectInfo}黑名单。。。')
    queryScanData = f"select ip from sync_ip_info where {projectInfo}=0"
    scanData = executeMysqlData(1,'read',queryScanData)
    ips = [item[θ] for item in scanData]
    if len(ips)!= 0:
        whileIPsList = ['<ips>']
        for i in whileIPsList:
            try:
                ips.remove(i)
                print(f'发现白名单 ip{i}在列表中, 尝试移除。。。')
                sql= f"""update sync_ip_info set {projectInfo}=1 where ip='{i}' and {projectInfo}=θ"""
                executeMysqlData(1,'write',sql)
                print (f'白名单 ip{i}移除完成')
            except:
                pass
        print (f'找到未同步的 ip{len(ips)}个')
        try:
            firewallRuleName,capacityFirewall = listLessThan5kFirewallRule(credentialsCST,projectInfo)
        except:
            firewallRuleName = None
        if firewallRuleName is not None:
            print (f'找到防火墙规则{firewallRuleName}, 尝试写入...')
            while 1:
                resultAddIP = addSourceIPToFirewallRule(credentialsCST,projectInfo,firewallRuleName,ips[θ:capacityFirewall])
                if resultAddIP is None:
                    print (f'更新黑名单ip成功,同步数据库中。。。')
                    for i in ips:
                        sql= f"""update sync_ip_info set {projectInfo}=1 where ip='{i}' and {projectInfo}=θ"""
                        executeMysqlData(1,'write', sql)
                    print (f'数据库同步完成')
                ips = ips[capacityFirewall:]
                if len(ips) > θ:
                    print (f'防火墙规则{firewallRuleName}写入完成,还剩下{len(ips)}个ip')
                    for i in range (1,1000):
                        firewallRuleName = "blocklist" + str(i)
                        resultAddPolicy = newFirewallPolicy(credentialsCST,projectInfo,firewallRuleName,ips[0:5000])
                        if resultAddPolicy == 'already exists':
                            i += 1
                        else:
                            print (f"防火墙规则{firewallRuleName}创建并写入成功!")
                            break
                        print (f'更新黑名单ip成功,同步数据库中。。')
                        for i in ips[θ:5000]:
                            sql= f"""update sync_ip_info set {projectInfo}=1 where ip='{i}' and {projectInfo}=θ"""
                            executeMysqlData(1,'write', sql)
                        print (f'数据库同步完成')
                    ips = ips[5001:]
                    if len(ips)>0:
                        print (f'防火墙规则{firewallRuleName}写入完成,还剩下{len(ips)}个ip')
                    else:
                        print (f"本次黑名单同步完成! ")
                        break
        else:
            while 1:
                for i in range (1,1000):
                    firewallRuleName = "blocklist" + str(i)
                    resultAddPolicy = newFirewallPolicy(credentialsCST,projectInfo,firewallRuleName,ips[0:5000])
                    if resultAddPolicy == 'already exists':
                        i += 1
                    else:
                        print (f"防火墙规则{firewallRuleName}创建并写入成功! ")
                        break
                    print (f'更新黑名单 ip成功,同步数据库中。。')
                    for i in ips[0:5000]:
                        sql= f"""update sync_ip_info set {projectInfo}=1 where ip='{i}' and {projectInfo}=0"""
                        executeMysqlData(1,'write', sql)
                    print (f'数据库同步完成')
                ips = ips[5001:]
                if len(ips) >0:
                    print (f'防火墙规则{firewallRuleName}写入完成,还剩下{len ips}个 ip')
                else:
                    print (f"本次黑名单同步完成! ")
                    break