ISPConfig 3 Update a DNS 'A' Record programmatically

Discussion in 'General' started by sghazagh, Sep 6, 2019.

  1. sghazagh

    sghazagh Member

    Hi every one,
    Is there any way to update only one 'A' record of one DNS zone of one domain in ISPConfig 3 programmatically via shell or php script?

    I use one subdomain A record to point to my home server which has no Static IP.
    Home server uploads the last public IP to my ISPConfig server outside the home and I need to update the A record of my subdomain to always have my latest home IP address so I can use my subdomain all the time and it resolves to my home dynamic address.

    Is there anyway I can make a script in either php or shell that I can use cron to update that record in ISPConfig?

    Any help would be appreciated,
     
  2. till

    till Super Moderator Staff Member ISPConfig Developer

    Yes, you can do that with the ISPConfig remote API. You can find examples here in the forum and in the remote_client folder of the ISPConfig tar.gz file.
     
  3. sghazagh

    sghazagh Member

    Thanks till,
    Functions of ISPconfig are endless, what a great application...
    I could manage to update my record properly as per API sample function 'dns_a_update.php'

    Thank you
     
    ahrasis and till like this.
  4. Tuumke

    Tuumke Active Member

    I'm sorry to hijack this thread, sort of :)
    I started looking into this. What i'm wonder is, do i need to update the serial as well? Or does that happen automaticly? Since the documentation is talking about the serial.
    Code:
    dns_a_update($session_id, $client_id, $primary_id, $params);
    Description:
    Updates an IPv4 record if type is a.
    
    Input Variables:
    $session_id, $client_id, $primary_id, $params
    
    Parameters (in $params):
    server_id  (int(11))
    zone  (int(11))
    name  (varchar(64))
    type  (enum('a','aaaa','alias','cname','hinfo','mx''naptr','ns','ptr','rp','srv','txt'))
    data  (varchar(255))
    aux  (int(11))
    ttl  (int(11))
    active  (enum('n','y'))
    stamp  (timestamp)
    serial  (int(10))
    
    Output:
    Returns the number of affected rows.
     
  5. till

    till Super Moderator Staff Member ISPConfig Developer

    You have to update the serial of the zone yourself if I remember correctly.
     
  6. Tuumke

    Tuumke Active Member

    At least i found a way to read current settings of my A record including serial ;)
    Will put my sh script here when im done.
     
    Last edited: Dec 3, 2019
    ahrasis and till like this.
  7. Tuumke

    Tuumke Active Member

    Where do i check what is going wrong in the ISPConfig logs?
    Trying with:
    Code:
    params=$( jq -n \
            --arg j_server_id "$server_id" \
            --arg j_zone "$zone" \
            --arg j_name "$name" \
            --arg j_type "$type" \
            --arg j_data "$currentip" \
            --arg j_aux "$aux" \
            --arg j_ttl "$ttl" \
            --arg j_active "$active" \
            --arg j_stamp "$stamp" \
            --arg j_serial "$new_serial" \
            '{server_id: $j_server_id, zone: $j_zone, name: $j_name, type: $j_type, data: $j_data, aux: $j_aux, ttl: $j_ttl,  active: $j_active, stamp: $j_stamp, serial: $j_serial}' )
    
    result=`restCall dns_a_update "{\"session_id\": \"$session_id\",\"client_id\":\"1\",\"primary_id\":\"128\",\"params\":\"$params\"}" | jq -r ".response"`
    but all i get is 'false'

    nvm. Went with a single restCall and no jq pipeline. Got:
    {"code":"invalid_data","message":"The JSON data sent to the api is invalid","response":false}

    This is the json:
    Code:
    {
      "server_id": "1",
      "zone": "3",
      "name": "test",
      "type": "A",
      "data": "1.1.1.1",
      "aux": "0",
      "ttl": "300",
      "active": "Y",
      "stamp": "2019-12-02 18:04:46",
      "serial": "2019120301"
    }
    -edit-
    As per the documentation, also client_id, primary_id and... 1 more are given before the params
     
    Last edited: Dec 3, 2019
  8. Tuumke

    Tuumke Active Member

    This is my script so far which gives a 'false' as return when trying to update the record.
    So far, i can read the current record i want but i cannot modify it. There is something wrong with the JSON i send?
    Code:
    #!/usr/bin/env bash
    
    set -e
    debug="false"
    
    if [ $debug = "true" ];
    then
            echo "###### DEBUGGING IS ON ########"
    fi
    
    ## Get current IP address
    currentip=`curl -sSk https://watismijnip.info/ | sed -E 's/<[^>]*>//g'`
    if [ $debug = "true" ]; then
            echo "Current IP: $currentip"
    fi
    
    
    exportfile='currentdata.json'
    if [ -f $exportfile ]; then
            rm $exportfile
    fi
    
    
    ## Login settings
    remote_user='remoteuser'
    remote_password='remotepasssword'
    remote_url='https://domain.tld:8080/remote/json.php'
    
    
    # restCall method data
    restCall() {
        curl -sSk -X POST -H "Content-Type: application/json" -H "Cache-Control: no-cache" -d "${2}" "${remote_url}?${1}"
    }
    
    # Log in
    session_id=`restCall login "{\"username\": \"${remote_user}\",\"password\": \"${remote_password}\"}" | jq -r '.response'`
    if [[ $isession == "false" ]]; then
        echo "Login failed!"
        exit 1
    else
        echo "Logged in. Session is: $session_id"
    fi
    
    ## Define current data for the A record
    currentdata=`restCall dns_a_get "{\"session_id\": \"$session_id\",\"primary_id\":\"128\"}" | jq -r ".response"`
    echo $currentdata > currentdata.json
    ## Define data needed for JSON put
    server_id=`jq -r ".server_id" $exportfile`
    zone=`jq -r ".zone" $exportfile`
    name=`jq -r ".name" $exportfile`
    type=`jq -r ".type" $exportfile`
    data=`jq -r ".data" $exportfile`
    aux=`jq -r ".aux" $exportfile`
    ttl=`jq -r ".ttl" $exportfile`
    active=`jq -r ".active" $exportfile`
    stamp=`jq -r ".stamp" $exportfile`
    declare serial=`jq -r ".serial" $exportfile`
    
    if [ $debug == "true" ]; then
            echo "Server_id: $server_id"
            echo "Zone: $zone"
            echo "Name: $name"
            echo "Type: $type"
            echo "Data: $data"
            echo "Aux: $aux"
            echo "TTL: $ttl"
            echo "Active: $active"
            echo "Stamp: $stamp"
            echo "Serial: $serial"
    fi
    
    declare -i serial_date=${serial:0:8}
    declare -i count=${serial:8:2}
    current_date=`date +%Y%m%d`
    
    if [ $debug == "true"  ]; then
            echo "Serial_date: $serial_date"
            echo "Current_date: $current_date"
            echo "Count: $count"
    fi
    
    if [ $serial_date -gt $current_date ]; then
            count=$(( count + 1 ))
            if [ $count > 99 ]; then
                    declare -i serial_date=`$(( $serial_date +1 ))`
                    echo "L42:$serial_date"
                    declare -i count=0
            fi
            count=`printf "%02d" "$count"`
            declare -i new_serial="$serial_date""$count"
    else
    # test
            declare -i new_serial="$current_date""01"
    fi
    
    if [ $debug == "true" ]; then
            echo "New_serial: $new_serial"
    fi
    
    params=$( jq -n \
            --arg j_server_id "$server_id" \
            --arg j_zone "$zone" \
            --arg j_name "$name" \
            --arg j_type "$type" \
            --arg j_data "$currentip" \
            --arg j_aux "$aux" \
            --arg j_ttl "$ttl" \
            --arg j_active "$active" \
            --arg j_stamp "$stamp" \
            --arg j_serial "$new_serial" \
            '{server_id: $j_server_id, zone: $j_zone, name: $j_name, type: $j_type, data: $j_data, aux: $j_aux, ttl: $j_ttl,  active: $j_active, stamp: $j_stamp, serial: $j_serial}' )
    
    #result=`restCall dns_a_update "{\"session_id\": \"$session_id\",\"client_id\":\"1\",\"primary_id\":\"128\",\"params\":\"$params\"}" | jq -r ".response"`
    
    restCall dns_a_update "{\"session_id\": \"$session_id\",\"client_id\":\"1\",\"primary_id\":\"128\",\"params\":\"$params\"}"
    
    echo $result
    
    
    echo $params
    
    ## Cleanup and log out
    if [ -f $exportfile ]; then
            rm $exportfile
    fi
    
    
    # Log out
    if [[ `restCall logout "{\"session_id\": \"$session_id\"}" |jq -r .response` == "true" ]]; then
        echo "Logout successful."
        exit 0
    else
        echo "Logout failed!"
        exit 1
    fi
    
    
     
  9. Tuumke

    Tuumke Active Member

    Okai, i managed to update my record via bash script :)
    Need to build in a check to see if record IP address and current IP address are different or not :)
     
  10. ahrasis

    ahrasis Well-Known Member HowtoForge Supporter

Share This Page