同步多个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