Skip to content

Conversation

lokst
Copy link
Contributor

@lokst lokst commented Sep 17, 2025

Add support for batch change zone records endpoint

Addresses https://github.com/dnsimple/dnsimple-app/issues/31926
Belongs to https://github.com/dnsimple/dnsimple-business/issues/2263

✅ Tested in Sandbox

Test script for Sandbox

import os
import random
from dnsimple import Client
from dnsimple.struct.batch_change_zone_records import (
    BatchChangeZoneRecordsInput,
    BatchChangeZoneRecordsUpdateInput,
    BatchChangeZoneRecordsDeleteInput
)
from dnsimple.struct.zone_record import ZoneRecordInput

# Configuration
token = os.getenv('TOKEN')
if not token:
    print("ERROR: Set TOKEN environment variable")
    exit(1)

account_id = os.getenv('ACCOUNT_ID', '1640')
zone_name = os.getenv('ZONE_NAME', 'akairanger.be')

# Generate random IP for testing
def random_ip():
    return f"192.168.{random.randint(1, 254)}.{random.randint(1, 254)}"

# Initialize client
client = Client(sandbox=True, access_token=token)
zones = client.zones

print("=== Simple Batch Change Test ===")
print(f"Zone: {zone_name}")

try:
    # Step 1: Create records
    print("\n1. Creating records...")
    create_batch = BatchChangeZoneRecordsInput(
        creates=[
            ZoneRecordInput('test', 'A', random_ip()),
            ZoneRecordInput('', 'A', random_ip())
        ]
    )

    create_response = zones.batch_change_records(account_id, zone_name, create_batch)
    record_ids = [record.id for record in create_response.data.creates]
    print(f"✓ Created records: {record_ids}")

    print("Create response details:")
    for i, record in enumerate(create_response.data.creates):
        print(f"  Record {i+1}: ID={record.id}, name='{record.name}', type={record.type}, content='{record.content}'")

    # Step 2: Update and delete
    print("\n2. Updating and deleting...")
    update_batch = BatchChangeZoneRecordsInput(
        creates=[
            ZoneRecordInput('test', 'A', random_ip()),
            ZoneRecordInput('', 'A', random_ip())
        ],
        updates=[
            BatchChangeZoneRecordsUpdateInput(record_ids[0], content=random_ip())  # Update first
        ],
        deletes=[
            BatchChangeZoneRecordsDeleteInput(record_ids[1])  # Delete second
        ]
    )

    update_response = zones.batch_change_records(account_id, zone_name, update_batch)
    print(f"✓ Created: {len(update_response.data.creates)} records")
    print(f"✓ Updated: {len(update_response.data.updates)} records")
    print(f"✓ Deleted: {len(update_response.data.deletes)} records")

    print("Combined response details:")
    if update_response.data.creates:
        print("  Creates:")
        for i, record in enumerate(update_response.data.creates):
            print(f"    Record {i+1}: ID={record.id}, name='{record.name}', type={record.type}, content='{record.content}'")

    if update_response.data.updates:
        print("  Updates:")
        for i, record in enumerate(update_response.data.updates):
            print(f"    Record {i+1}: ID={record.id}, name='{record.name}', type={record.type}, content='{record.content}'")

    if update_response.data.deletes:
        print("  Deletes:")
        for i, record in enumerate(update_response.data.deletes):
            print(f"    Record {i+1}: ID={record.id}")

    print("\n🎉 All tests passed!")

except Exception as e:
    print(f"\n❌ Test failed: {e}")
    exit(1)

Output

=== Simple Batch Change Test ===
Zone: akairanger.be

1. Creating records...
✓ Created records: [3422502, 3422503]
Create response structure:
  Response type: <class 'dnsimple.response.Response'>
  Response.data type: <class 'dnsimple.struct.batch_change_zone_records.BatchChangeZoneRecordsResponse'>
  Response.data: BatchChangeZoneRecordsResponse()
  Response.data.__dict__: {'creates': [ZoneRecord(), ZoneRecord()], 'updates': [], 'deletes': []}
  creates type: <class 'list'>
    Record 0: <class 'dnsimple.struct.zone_record.ZoneRecord'> - {'id': 3422502, 'zone_id': 'akairanger.be', 'parent_id': None, 'name': 'test', 'content': '192.168.90.144', 'ttl': 3600, 'priority': None, 'type': 'A', 'regions': ['global'], 'system_record': False, 'created_at': '2025-09-18T04:45:05Z', 'updated_at': '2025-09-18T04:45:05Z'}
    Record 1: <class 'dnsimple.struct.zone_record.ZoneRecord'> - {'id': 3422503, 'zone_id': 'akairanger.be', 'parent_id': None, 'name': '', 'content': '192.168.217.131', 'ttl': 3600, 'priority': None, 'type': 'A', 'regions': ['global'], 'system_record': False, 'created_at': '2025-09-18T04:45:05Z', 'updated_at': '2025-09-18T04:45:05Z'}

2. Updating and deleting...
✓ Created: 2 records
✓ Updated: 1 records
✓ Deleted: 1 records
Combined response structure:
  Response type: <class 'dnsimple.response.Response'>
  Response.data type: <class 'dnsimple.struct.batch_change_zone_records.BatchChangeZoneRecordsResponse'>
  Response.data: BatchChangeZoneRecordsResponse()
  Response.data.__dict__: {'creates': [ZoneRecord(), ZoneRecord()], 'updates': [ZoneRecord()], 'deletes': [BatchChangeZoneRecordsDeleteResponse()]}
  creates type: <class 'list'>
    Create 0: <class 'dnsimple.struct.zone_record.ZoneRecord'> - {'id': 3422504, 'zone_id': 'akairanger.be', 'parent_id': None, 'name': 'test', 'content': '192.168.152.43', 'ttl': 3600, 'priority': None, 'type': 'A', 'regions': ['global'], 'system_record': False, 'created_at': '2025-09-18T04:45:05Z', 'updated_at': '2025-09-18T04:45:05Z'}
    Create 1: <class 'dnsimple.struct.zone_record.ZoneRecord'> - {'id': 3422505, 'zone_id': 'akairanger.be', 'parent_id': None, 'name': '', 'content': '192.168.254.80', 'ttl': 3600, 'priority': None, 'type': 'A', 'regions': ['global'], 'system_record': False, 'created_at': '2025-09-18T04:45:05Z', 'updated_at': '2025-09-18T04:45:05Z'}
  updates type: <class 'list'>
    Update 0: <class 'dnsimple.struct.zone_record.ZoneRecord'> - {'id': 3422502, 'zone_id': 'akairanger.be', 'parent_id': None, 'name': 'test', 'content': '192.168.81.172', 'ttl': 3600, 'priority': None, 'type': 'A', 'regions': ['global'], 'system_record': False, 'created_at': '2025-09-18T04:45:05Z', 'updated_at': '2025-09-18T04:45:05Z'}
  deletes type: <class 'list'>
    Delete 0: <class 'dnsimple.struct.batch_change_zone_records.BatchChangeZoneRecordsDeleteResponse'> - {'id': 3422503}

🎉 All tests passed!

@lokst lokst self-assigned this Sep 17, 2025
@lokst lokst marked this pull request as ready for review September 18, 2025 04:47
@lokst lokst requested a review from jacegu September 18, 2025 04:48
lokst and others added 2 commits September 18, 2025 17:23
Co-authored-by: Javier Acero <javier.acero@dnsimple.com>
@lokst lokst requested a review from jacegu September 18, 2025 09:36
@lokst lokst merged commit c820e04 into main Sep 19, 2025
3 checks passed
@lokst lokst deleted the batch-change-zone-records branch September 19, 2025 04:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants