Information Technology Grimoire

Version .0.0.1

IT Notes from various projects because I forget, and hopefully they help you too.

Python3 Digital Ocean Bulk DNS Editor

I needed to import a bunch of dns records into Digital Ocean. Their API is great!

import requests

API_ENDPOINT = "https://api.digitalocean.com/v2/domains"
HEADERS = {
    "Authorization": "Bearer dop_v1_1blehblehblehgetyourapiF",
    "Content-Type": "application/json"
}

def domain_exists(domain):
    response = requests.get(API_ENDPOINT, headers=HEADERS)
    if response.status_code == 200:
        domains = [d['name'] for d in response.json()['domains']]
        return domain in domains
    return False

def del_create_or_update_record(records_endpoint, record_type, name, data, priority=None, ttl=300):
    # Check if the record already exists.
    current_records = requests.get(records_endpoint, headers=HEADERS).json()["domain_records"]
    matching_records = [r for r in current_records if r['type'] == record_type and r['name'] == name]
    if matching_records:
        # If record exists, update it.
        update_endpoint = f"{records_endpoint}/{matching_records[0]['id']}"
        requests.put(update_endpoint, headers=HEADERS, json={"data": data, "ttl": ttl, "priority": priority})
    else:
        # If record doesn't exist, create it.
        requests.post(records_endpoint, headers=HEADERS, json={"type": record_type, "name": name, "data": data, "ttl": ttl, "priority": priority})

def create_or_update_record(records_endpoint, record_type, name, data, priority=None, ttl=300):
    # Check if the record already exists.
    current_records = requests.get(records_endpoint, headers=HEADERS).json()["domain_records"]
    
    # Determine matching criteria based on record type.
    if record_type == "MX":
        matching_records = [r for r in current_records if r['type'] == record_type and r['name'] == name and r['priority'] == priority]
    else:
        matching_records = [r for r in current_records if r['type'] == record_type and r['name'] == name]
    
    if matching_records:
        # If record exists, update it.
        update_endpoint = f"{records_endpoint}/{matching_records[0]['id']}"
        requests.put(update_endpoint, headers=HEADERS, json={"data": data, "ttl": ttl, "priority": priority})
    else:
        # If record doesn't exist, create it.
        requests.post(records_endpoint, headers=HEADERS, json={"type": record_type, "name": name, "data": data, "ttl": ttl, "priority": priority})


def create_or_update_domain(domain, ip, google_site_validation=None):
    records_endpoint = f"{API_ENDPOINT}/{domain}/records"

    # Create or update the domain itself
    if not domain_exists(domain):
        requests.post(API_ENDPOINT, headers=HEADERS, json={"name": domain, "ip_address": ip})

    # Update or create A record
    create_or_update_record(records_endpoint, "A", "@", ip, ttl=300)

    # Update or create CNAME record
    create_or_update_record(records_endpoint, "CNAME", "www", domain + ".", ttl=300)

    # Update or create MX records
    mx_records_with_priorities = [
        ("mx1.emailsrvr.com.", 10),
        ("mx2.emailsrvr.com.", 20)
    ]
    for mx_record, priority in mx_records_with_priorities:
        create_or_update_record(records_endpoint, "MX", "@", mx_record, priority=priority, ttl=300)

    # Update or create NS records
    for ns_record in ["ns1.digitalocean.com.", "ns2.digitalocean.com.", "ns3.digitalocean.com."]:
        create_or_update_record(records_endpoint, "NS", "@", ns_record, ttl=1800)

    # Create or update TXT record
    base_txt_data = f"v=spf1 include:emailsrvr.com; v=DMARC1; p=none; rua=mailto:dmarc@{domain};"
    
    # Append google-site-verification if available
    if google_site_validation:
        base_txt_data += f" {google_site_validation}"
    
    create_or_update_record(records_endpoint, "TXT", "@", base_txt_data, ttl=300)

    # Provide feedback.
    return f"Domain {domain} processed successfully."


# Example usage domain name, IP for A records, and google-site-verification
domains_data = {
    "12holeocarina.com": ["162.243.46.68", "google-site-verification=9nEZjtkJhH7MXf0PjPTx7tvUj0vvDJGFVpVC2S2B7CI"],
    "6holeocarina.com": ["162.243.46.68", "google-site-verification=1TXjMGFEFtZPRUwrvLG0_DTNoFATYNoBpmvj5ggKue4"],
    "aquaponics-system.com": ["162.243.46.68", "google-site-verification=YsSn2FjQVs3Wi1O2jqAiORM1dcDjQe1w-FP5HgrxZi8"],
    "bakersfieldcleaningservices.com": ["159.203.147.69", "google-site-verification=FQkZBS_Qkn4kFPNKs86qokLGtailMiz9yS_8iS_T0w0"],
    "dependablenursestaffing.com": ["159.203.147.69", "google-site-verification=22PVOY0j-5N1GUeQf-XPO-H3WF_Vksry9mxkq4Qtf28"],
    "somesite.com": ["162.243.46.68", "google-site-verification=lPI8XX2zF_deVkm8vaQoEPT8rc3kMVRe6s1hRnxAYAY"],
    "emailmarketinglabs.com": ["159.203.147.69", "google-site-verification=MyJfpHUoZ8oJZW9cICSydud8Ug5395SCBeBOQtt3JjM"],
    "expert-marketer.com": ["159.203.147.69", "google-site-verification=5MN7qZdG6R_NxmsQ9U_si-yc13322tmdP2vx-1fkDDA"],
    "followupemails.com": ["18.224.161.133", "google-site-verification=PNyYxBM2MzcgJ0nmIfyPg8YaQrNy0Ucg1w0irsOGFL8"],
    "hollowedstone.com": ["3.17.49.246", "google-site-verification=L5Y5qJeiynPf_qnsEf5QuZ0pTPXLov5dOYTazM9lM3U"],
    "how-to-get-credit.com": ["159.203.147.69", "google-site-verification=V0PYyh7qiu8llosTZV4gpFnDbQNsP-AFcaRtD3YcgTA"],
    "somedomain.com": ["45.55.116.11", "google-site-verification=xxE0aeIHUKBngeHc5BVdGDOw2sayhxeX7Wi4cWgqB4s"],
    "jamesfraze.com": ["159.203.147.69", "google-site-verification=6BXjzmqyyySh9U-zOpk-lz1BTBMuegraNxIXa-M1-cY"],
    "localmasterminds.com": ["159.203.147.69", "google-site-verification=Nv6d9LilWri7DTHQQN1YWT1vHg4d8L18iTbnVd51fzQ"],
    "malchias.com": ["159.203.147.69", "google-site-verification=zrNgka4J-XnwzCO1LOpKOmEEKP9zUV-LnTtGoFaNUK4"],
    "nicebanker.com": ["159.203.147.69", "google-site-verification=jBV_Q0Ixepbffe0UjoDUy3aQBdx3JemdMFYu2pnc7Sw"],
    "somesite.com": ["3.130.72.10", "google-site-verification=WL1z6HkBiwl6WHdq5ayIogefGdHxLfbjaxHBXPpnYgw"],
    "onlinewholesalehomes.com": ["159.203.147.69", "google-site-verification=wEB6uYxGZ25OQmagp5Hk1qF-Eo3BFOsUDwk7dcDVN9c"],
    "overnightcashbandit.com": ["159.203.147.69", "google-site-verification=xX6hsX4tRTHsd7RreKxvaZIWBFgPV9J1Grp12iVjt-A"],
    "paidpropertyfinder.com": ["159.203.147.69", "google-site-verification=A2j-qLZJseaAC4BY2l3KJApOZcMAZbhnG71ZWGD3ldc"],
    "perfectvacationpackages.com": ["52.15.70.99", "google-site-verification=HqaVenkcoK_oEaB-d8_KdhQKttKJnOs1cAMdcX337OI"],
    "phoenixseoservices.com": ["159.203.147.69", "google-site-verification=guZ54mip0yWNg_Q5NE-OPGRKLTK7acuaVRZC3Z9wyHg"],
    "redmountainadmin.com": ["159.203.147.69", "google-site-verification=1SAMjNYHCelXtxzvanMfxILcPvuKwzbpEambW8WB7s8"],
    "resumestation.com": ["159.203.147.69", "google-site-verification=X7BjPOhi36Ydl5MD8jOWHlVMuQ1t-PcZgk3CZZgmQfU"],
    "somesite.com": ["162.243.23.116", "google-site-verification=_yNO75ldL6Vdq6wCYnzrD-C9-ftZHWUpogEnF2AJnIM"],
    "sanantoniorei.com": ["159.203.147.69", "google-site-verification=ptDI5rERxSzF9tchsUvfZyIeRYAH5myk8Ld3y4Kqdmc"],
    "sellyourhomefastonline.com": ["45.55.116.11", "google-site-verification=nmA7heGzSegj7EUEXYjP8Gfkwwu3pCrgrVCrGEzopD8"],
    "seniorassistedlivingcare.com": ["159.203.147.69", "google-site-verification=HTs6mT7QJOJnt8gucKA9or7RoqnA6yxpvIHaaDHq0h8"],
    "seocompanyphoenix.com": ["159.203.147.69", "google-site-verification=nCVbjb9VKVyRZDt1-yCeM5BWmDPpCrBqpw3maGhe5d8"],
    "sfxmakeupartist.com": ["159.203.147.69", "google-site-verification=w79yM0bOBCXI-oybleT1C4k6fBhkslY4Bq5MeBYa9Ys"],
    "snapcleaningservices.com": ["159.203.147.69", "google-site-verification=3EoKigUFV8hHRtW3Yv7x65sIsFuF6fbG7-mt95ivjd0"],
    "tiredlandlordhelp.com": ["159.203.147.69", "google-site-verification=Hki2z62s0iXzS_8ZLkPlSRfj_GMuAZRPgj8_9phMVxs"],
    "truehomelease.com": ["159.203.147.69", "google-site-verification=Wm79o-6e4vtR8IpRm_4I4VhX664cOUWd8JalhTzPwy0"],
    "txhomesteadprepper.com": ["159.203.147.69", "google-site-verification=Gvm0QflkZv_cNASRncQkxxpKXE4loA2dmZbkwbvGdto"],
    "workerboost.com": ["159.203.147.69", "google-site-verification=ySLqZM9_RXHFmCmqKw0140p552LGww7jZ18NRqT2_RM"]
}

for domain, values in domains_data.items():
    ip = values[0]
    google_site_validation = values[1] if len(values) > 1 else None
    result = create_or_update_domain(domain, ip, google_site_validation)
    print(result)
Last updated on 11 Oct 2023
Published on 11 Oct 2023