Skip to content

Instantly share code, notes, and snippets.

@jvanasco
Last active May 10, 2024 17:21
Show Gist options
  • Save jvanasco/5b459923d887ec8dfde51a0d529a2242 to your computer and use it in GitHub Desktop.
Save jvanasco/5b459923d887ec8dfde51a0d529a2242 to your computer and use it in GitHub Desktop.
Cloudflare Zone Updates - migrate an IP address across your account, and enable CT monitoring
"""
Cloudflare Zone Updates - migrate an IP address across your account, and enable CT monitoring
Usage:
This expects the Cloudflare object to be configured with an API token
as-is, this can be run if the token is exported into the environment
otherwise, the CF object must be manually created and use an api token
*api keys will not work*
I ran into a ephemeral non-repeatable issues on the CT updates on some requests.
if that happens, just rerun the script. it should work.
i think this may be an api ratelimit issue
"""
# pypi
import CloudFlare
import requests
# ==============================================================================
def migrate_ip_address(
cf: CloudFlare.CloudFlare, # must be RAW
ip_old: str,
ip_new: str,
list_all: bool = False,
):
print("migrate_ip_address")
page_number: int = 0
while True:
page_number += 1
print("Cloudflare Zones %s:" % page_number)
raw_results = cf.zones.get(params={'per_page':100,'page':page_number})
for zone in raw_results['result']:
zone_id = zone["id"]
zone_name = zone["name"]
print("zone_id=%s zone_name=%s" % (zone_id, zone_name))
d_page_number: int = 0
while True:
d_page_number += 1
try:
raw_dns_records = cf.zones.dns_records.get(zone_id, params={'per_page':100,'page':d_page_number})
except CloudFlare.exceptions.CloudFlareAPIError as e:
exit("/zones/dns_records.get %d %s - api call failed" % (e, e))
# then all the DNS records for that zone
for dns_record in raw_dns_records["result"]:
r_name = dns_record["name"]
r_type = dns_record["type"]
r_value = dns_record["content"]
r_id = dns_record["id"]
modification_needed: bool = r_value == ip_old
if list_all or modification_needed:
print("\t", r_id, r_name, r_type, r_value)
if modification_needed:
print("\t", "modifying: %s" % r_id)
dns_record["content"] = ip_new
dns_result = cf.zones.dns_records.patch(zone_id, r_id, data=dns_record)
d_total_pages = raw_dns_records['result_info']['total_pages']
if d_page_number == d_total_pages:
break
total_pages = raw_results['result_info']['total_pages']
if page_number == total_pages:
break
def enable_ct_monitoring(
cf: CloudFlare.CloudFlare, # must be RAW
):
print("enable_ct_monitoring")
_api_url = "https://api.Cloudflare.com/client/v4/zones/%s/ct/alerting"
# prep requests, as the cloudflare library doesn't handle this nicely
s = requests.Session()
s.headers.update(
{
"Content-Type": "application/json",
"Authorization": "Bearer %s" % cf._base.api_token,
}
)
page_number: int = 0
while True:
page_number += 1
print("Cloudflare Zones %s:" % page_number)
raw_results = cf.zones.get(params={'per_page':100,'page':page_number})
for zone in raw_results['result']:
zone_id = zone["id"]
zone_name = zone["name"]
print("zone_id=%s zone_name=%s" % (zone_id, zone_name))
alerting_config = s.get(_api_url % zone_id)
alerting_config_json = alerting_config.json()
if alerting_config.status_code != 200:
print("ERROR. Possible API ratelimit. retry or troubleshoot")
continue
enabled = True if alerting_config_json["result"]["enabled"] else False
print("\t", "enabled" if enabled else "!!!! DISABLED")
if not enabled:
print("\t", "Updating...")
updated_config = s.patch(_api_url % zone_id, data='{"enabled":true}')
if updated_config.status_code == 200:
print("\t", "Success")
else:
print("\t", "Failure")
total_pages = raw_results['result_info']['total_pages']
if page_number == total_pages:
break
if __name__ == "__main__":
cf = CloudFlare.CloudFlare()
migrate_ip_address(cf, ip_old="OLD", ip_new="NEW")
enable_ct_monitoring(cf)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment