Child pages
  • Guide to Custom dnsadmin Plugins - The Remote Module
Skip to end of metadata
Go to start of metadata

Introduction

The Remote module communicates with other servers in the DNS cluster.Store the Remote module as a file with the .pm extension in the /usr/local/cpanel/Cpanel/NameServer/Remote/ directory, which corresponds to the Cpanel::NameServer::Remote namespace.

Notes:

  • Remote modules require that you use the cPanel::PublicAPI (cPanel & WHM version 54 and later) or Cpanel::PublicAPI (cPanel & WHM version 11.52 and earlier) clients.
  • When you create a Remote module, you must use the PublicAPI new() method.
  • You may call one command method within another command method.
    • Whenever this occurs, the command method that called another method must modify the dnsuniqid value.
    • We recommend that you append Perl's _$int function to the dnsuniqid value.

You can find additional example modules in the /usr/local/cpanel/Cpanel/NameServer/Remote/ directory on your cPanel & WHM server.

Parameters

When you write a Remote module, you can use the following variables in your code:

VariableDescription
accesshash

The access hash password in the DNS configuration file in the /var/cpanel/cluster/username/config/ directory, where username represents the authenticated WHM account's username.

To create or view an access hash, use WHM's Remote Access Key interface (WHM >> Home >> Clusters >> Remote Access Key). 

Warning:

We deprecated WHM's Remote Access Key feature in cPanel & WHM version 64. We strongly recommend that you use API tokens instead.

dnsroleThe remote server's DNS role.
hostThe host to which the module connects.
local_timeoutThe amount of time to wait to send an HTTP request before the system times out, in seconds.
logger

Required

The Cpanel::Logger instance to use.

Note:

You must use the bless function to pass this value in the module's final hash. For more information, read the Perl documentation on the bless function.

original_request_timeThe time at which the user called the DNS command, in Unix time format.
output_callback

Required

A subroutine reference that handles display data.

Note:

You must use the bless function to pass this value in the module's final hash. For more information, read the Perl documentation on the bless function.

queue_callback

Required

A subroutine reference to the subroutine that manages queue requests.

Note:

You must use the bless function to pass this value in the module's final hash. For more information, read the Perl documentation on the bless function.

remote_timeoutThe amount of time to wait to receive an HTTP request before the system times out, in seconds.
timeoutThe timeout to use.
token

The user's API token.

To create or view an API token, use WHM's Manage API Tokens interface (WHM >> Home >> Security Center >> Manage API Tokens). 

Note:

We introduced this functionality in cPanel & WHM version 64.

update_typeThe type of update.
userThe username in the DNS configuration file in the /var/cpanel/cluster/username/config/ directory, where username is the authenticated WHM account's username.

Parameters

Each command method must use the following parameters:

ParameterDescription
dnsuniqidThe command's unique identifier, which the method should use to ensure that the same system does not receive a command twice.
datarefA hash reference that contains a serialized version of arguments that the method passed to the command.
rawdataA hash reference that contains a raw URL version of the arguments that the method passed to the system.

For this reason, we recommend that you begin each method with the following line of code:

my ( $self, $dnsuniqid, $dataref, $rawdata ) = @_;

Returns

The dnsadmin system returns data as output and parameters, because the system executes processes through output data. The base class implements this output as the output() subroutine. This subroutine relies on the output_callback value that your module passes with the bless function into the new() subroutine.

Command methods return a hash that contains two values:

ReturnTypeDescriptionPossible valuesExample
statusstringA constant that the Cpanel::NameServers::Constants namespace defines.

This value must be $Cpanel::NameServer::Constants::*, where * is one of the following constants:

  • ERROR_INVALID_RESPONSE_LOGGED
  • ERROR_GENERIC
  • ERROR_TIMEOUT
  • ERROR_GENERIC_LOGGED
  • ERROR_TIMEOUT_LOGGED
  • SUCCESS
  • QUEUE
  • DO_NOT_QUEUE
 Click to view...
$Cpanel::NameServer::Constants::QUEUE
messagestringA message of success, or a reason for failure.
  • OK
  • An error message.
OK

The _check_action() subroutine

The _check_action() subroutine returns proper data constants when the dnsadmin system sends or receives information. This subroutine checks remote systems' HTTP statuses, and determines whether the system can recover from errors.

Calls to this subroutine resemble the following examples:

_check_action($msg, $Cpanel::NameServer::Constants::QUEUE);
_check_action($msg, $Cpanel::NameServer::Constants::DO_NOT_QUEUE);

In these examples, the QUEUE and DO_NOT_QUEUE constants determine whether the system queues an action if it fails.

  • The QUEUE constant retries a failed action if the system determines that the action is recoverable.
  • The DO_NOT_QUEUE constant returns an error message for a failed action, and does not attempt to retry the action.

Note:

Use the $msg variable to pass in a message about the action that failed.

 

Command methods

You must implement each command that you pass to the dnsadmin system as a subroutine in your Remote module.

For more information about the required and optional command methods, read our Remote Module Command Methods documentation.

Warning:

You must include the following required methods in your module:

  • addzoneconf()
  • getallzones()
  • getips()
  • getpath()
  • getzone()
  • getzonelist()
  • getzones()
  • quickzoneadd()
  • removezone()
  • removezones()
  • savezone()
  • synczones()
  • version()
  • zoneexists()

Basic usage

Note:

Select the tab below for the desired cPanel & WHM version:

  • In cPanel & WHM version 54 and later, we ship the cPanel::PublicAPI module as an RPM of the CPAN module.
  • In cPanel & WHM version 11.52 and earlier, we shipped the Cpanel::PublicAPI module.

The following example code creates the  MyRemoteModule  server type:

# Package the module.
package Cpanel::NameServer::Remote::MyRemoteModule;

# Add use statements.
use strict;
use cPanel::PublicAPI                     ();
use cPanel::PublicAPI::WHM                ();
use cPanel::PublicAPI::WHM::DNS           ();
use cPanel::PublicAPI::WHM::CachedVersion ();
use Cpanel::Encoder::URI                  ();
use Cpanel::StringFunc::Match             ();
use Cpanel::StringFunc::Trim              ();
use Cpanel::NameServer::Remote            ();

our @ISA = ('Cpanel::NameServer::Remote');
our $VERSION = '1.2';


# Use the new() method to create a new LiveAPI object.
sub new {
    my $self = shift;
    my %OPTS = @_;
    $self = {%OPTS};
    bless $self;

    my $dnspeer        = $OPTS{'host'};
    my $user           = $OPTS{'user'};
    my $ip             = $OPTS{'ip'};
    my $pass           = $OPTS{'token'} || $OPTS{'pass'};
    my $remote_timeout = $OPTS{'timeout'};

    $self->{'name'}            = $dnspeer;
    $self->{'update_type'}     = $OPTS{'update_type'};
    $self->{'local_timeout'}   = $OPTS{'local_timeout'};
    $self->{'remote_timeout'}  = $OPTS{'remote_timeout'};
    $self->{'queue_callback'}  = $OPTS{'queue_callback'};
    $self->{'output_callback'} = $OPTS{'output_callback'};

    $self->{'publicapi'} = cPanel::PublicAPI->new(
        'host'       => $dnspeer,
        'user'       => $user,
        'keepalive'  => 1,
        'token'      => $APITOKEN,
        'debug'      => ( $OPTS{'debug'} || 0 ),
        'usessl'     => 1,
        'timeout'    => $remote_timeout,
        ( $ip ? ( 'ip' => $ip ) : () )
    );

    return $self;
}


# Create the getallzones command method.
sub getallzones {
    my ( $self, $unique_dns_request_id, $dataref, $rawdata ) = @_;
    require Cpanel::Gzip::ungzip;
    my $zdata  = $self->{'publicapi'}->getallzones_local($unique_dns_request_id);
    my $uzdata = Cpanel::Gzip::ungzip::gunzipmem($zdata);
    $self->output( $uzdata ne '' ? $uzdata : $zdata );
    return $self->_check_action( 'get all the zones', $Cpanel::NameServer::Constants::DO_NOT_QUEUE );
}


# Create the cleandns method, to remove unnecessary zones.
sub cleandns {
    my ( $self, $unique_dns_request_id, $dataref, $rawdata ) = @_;
    $self->output( $self->{'publicapi'}->cleandns_local($unique_dns_request_id) );
    return $self->_check_action( 'cleanup dns', $Cpanel::NameServer::Constants::DO_NOT_QUEUE );
}


# Create a method to remove a single zone.
sub removezone {
    my ( $self, $unique_dns_request_id, $dataref, $rawdata ) = @_;
    chomp( $dataref->{'zone'} );
    $self->output( $self->{'publicapi'}->removezone_local( $dataref->{'zone'}, $unique_dns_request_id ) . "\n" );
    return $self->_check_action( "remove the zone: $dataref->{'zone'}", $Cpanel::NameServer::Constants::QUEUE );
}


# Create a method to remove multiple zones.
sub removezones {
    my ( $self, $unique_dns_request_id, $dataref, $rawdata ) = @_;
    chomp( $dataref->{'zone'} );
    chomp( $dataref->{'zones'} );
    if ( isatleastversion( '11.24.2', $self->{'publicapi'}->cached_version() ) ) {
        $self->output( $self->{'publicapi'}->removezones_local( ( $dataref->{'zones'} || $dataref->{'zone'} ), $unique_dns_request_id ) . "\n" );
    }
    else {
        my $count = 0;
        foreach my $zone ( split( /\,/, ( $dataref->{'zones'} || $dataref->{'zone'} ) ) ) {
            $count++;
            $zone =~ s/^\s*|\s*$//g;
            print $self->{'publicapi'}->removezone_local( $zone, $unique_dns_request_id . '_' . $count ) . "\n";
            {
                my @check_action_results = $self->_check_action( "remove the zone(s): " . ( $dataref->{'zones'} || $dataref->{'zone'} ), $Cpanel::NameServer::Constants::QUEUE );
                return (@check_action_results) if $check_action_results[$Cpanel::NameServer::Constants::CHECK_ACTION_POSITION_IS_RECOVERABLE_ERROR];
            }
        }
    }
    return $self->_check_action( "remove the zone(s): " . ( $dataref->{'zones'} || $dataref->{'zone'} ), $Cpanel::NameServer::Constants::QUEUE );
}


# Create a method to force BIND to reload all zones.
sub reloadbind {
    my ( $self, $unique_dns_request_id, $dataref, $rawdata ) = @_;
    chomp( $dataref->{'zone'} );
    $self->output( $self->{'publicapi'}->reloadbind_local( $unique_dns_request_id, $dataref->{'zone'} ) . "\n" );
    return $self->_check_action( "reload bind", $Cpanel::NameServer::Constants::QUEUE );
}


# Create a method to force BIND to reload specific zones.
sub reloadzones {
    my ( $self, $unique_dns_request_id, $dataref, $rawdata ) = @_;
    chomp( $dataref->{'zone'} );
    if ( isatleastversion( '11.23.2', $self->{'publicapi'}->cached_version() ) ) {
        $self->output( $self->{'publicapi'}->reloadzones_local( $unique_dns_request_id, $dataref->{'zone'} ) . "\n" );
        {
            my @check_action_results = $self->_check_action( "reload zones $dataref->{'zone'}", $Cpanel::NameServer::Constants::QUEUE );
            return (@check_action_results) if $check_action_results[$Cpanel::NameServer::Constants::CHECK_ACTION_POSITION_STATUS] != $Cpanel::NameServer::Constants::SUCCESS;
        }
    }
    else {
        $self->output( $self->{'publicapi'}->reloadbind_local($unique_dns_request_id) . "\n" );
        {
            my @check_action_results = $self->_check_action( "reload bind", $Cpanel::NameServer::Constants::QUEUE );
            return (@check_action_results) if $check_action_results[$Cpanel::NameServer::Constants::CHECK_ACTION_POSITION_STATUS] != $Cpanel::NameServer::Constants::SUCCESS;
        }
    }
    return ( $Cpanel::NameServer::Constants::SUCCESS, 'OK' );
}

# Create a method to force BIND to reload configuration files.
sub reconfigbind {
    my ( $self, $unique_dns_request_id, $dataref, $rawdata ) = @_;
    if ( isatleastversion( '10.0.0', $self->{'publicapi'}->cached_version() ) ) {
        $self->output( $self->{'publicapi'}->reconfigbind_local($unique_dns_request_id) . "\n" );
    }
    else {
        $self->output( $self->{'publicapi'}->reloadbind_local( $unique_dns_request_id, $dataref->{'zone'} ) . "\n" );
    }
    return $self->_check_action( "reconfig bind", $Cpanel::NameServer::Constants::QUEUE );
}


# Create a method to save new records to existing zone files.
sub savezone {
    my ( $self, $unique_dns_request_id, $dataref, $rawdata ) = @_;
    chomp( $dataref->{'zone'} );
    $self->output( $self->{'publicapi'}->savezone_local( $dataref->{'zone'}, $dataref->{'zonedata'}, $unique_dns_request_id ) );
    return $self->_check_action( "save the zone $dataref->{'zone'}", $Cpanel::NameServer::Constants::QUEUE );
}


# Create a method to add multiple zones to a remote system and the config database.
sub synczones {
    my ( $self, $unique_dns_request_id, $dataref, $rawdata ) = @_;
    chomp( $dataref->{'zone'} );
    $rawdata =~ s/^dnsuniqid=[^\&]+\&//g;
    $rawdata =~ s/\&dnsuniqid=[^\&]+//g;
    local $self->{'publicapi'}->{'timeout'} = ( ( int( $self->{'local_timeout'} / 2 ) > $self->{'remote_timeout'} ) ? int( $self->{'local_timeout'} / 2 ) : $self->{'remote_timeout'} );
    $self->output( $self->{'publicapi'}->synczones_local( $rawdata, $unique_dns_request_id ) );
    return $self->_check_action( "sync zones: $dataref->{'zone'}", $Cpanel::NameServer::Constants::QUEUE );
}

# Create a method that adds a new zone to the system and saves its contents.
sub quickzoneadd {
    my ( $self, $unique_dns_request_id, $dataref, $rawdata ) = @_;
    if ( isatleastversion( '11.24.4', $self->{'publicapi'}->cached_version() ) ) {
        $self->output( $self->{'publicapi'}->quickzoneadd_local( $dataref->{'zone'}, $dataref->{'zonedata'}, $unique_dns_request_id ) );
    }
    else {
        if ( isatleastversion( '11.24.2', $self->{'publicapi'}->cached_version() ) ) {
            $self->output(
                $self->{'publicapi'}->synczones_local(
                'cpdnszone-' . Cpanel::Encoder::URI::uri_encode_str($dataref->{'zone'}) .
                '=' .
                Cpanel::Encoder::URI::uri_encode_str($dataref->{'zonedata'}) .
                '&',
                $unique_dns_request_id . '_1'
                )
            );
        }
        else {
            $self->output( $self->{'publicapi'}->addzoneconf_local( $dataref->{'zone'}, $unique_dns_request_id . '_1' ) );
            $self->output( $self->{'publicapi'}->savezone_local( $dataref->{'zone'}, $dataref->{'zonedata'}, $unique_dns_request_id . '_2' ) ) unless ( $self->{'publicapi'}->{'error'} ne '' );
        }
        $self->output( $self->{'publicapi'}->reconfigbind_local( $unique_dns_request_id . '_3' ) ) unless ( $self->{'publicapi'}->{'error'} ne '' );
    }
    return $self->_check_action( "quick add the zone $dataref->{'zone'}", $Cpanel::NameServer::Constants::QUEUE );
}

# Create a method to add a zone to the configuration database.
sub addzoneconf {
    my ( $self, $unique_dns_request_id, $dataref, $rawdata ) = @_;
    chomp( $dataref->{'zone'} );
    $self->output( $self->{'publicapi'}->addzoneconf_local( $dataref->{'zone'}, $unique_dns_request_id ) );
    return $self->_check_action( "add the zone $dataref->{'zone'}", $Cpanel::NameServer::Constants::QUEUE );
}

# Create a method to get the contents of a single zone file.
sub getzone {
    my ( $self, $unique_dns_request_id, $dataref, $rawdata ) = @_;
    chomp( $dataref->{'zone'} );
    $self->output( $self->{'publicapi'}->getzone_local( $dataref->{'zone'}, $unique_dns_request_id ) );
    return $self->_check_action( "get the zone $dataref->{'zone'}", $Cpanel::NameServer::Constants::DO_NOT_QUEUE );
}

# Create a method to get the contents of multiple zone files.
sub getzones {
    my ( $self, $unique_dns_request_id, $dataref, $rawdata ) = @_;
    chomp( $dataref->{'zone'} );
    chomp( $dataref->{'zones'} );
    require Cpanel::Gzip::ungzip;
    if ( isatleastversion( '11.1.0', $self->{'publicapi'}->cached_version() ) ) {
        my $zdata = $self->{'publicapi'}->getzones_local( ( $dataref->{'zones'} || $dataref->{'zone'} ), $unique_dns_request_id );
        my $uzdata = Cpanel::Gzip::ungzip::gunzipmem($zdata);
        $self->output( $uzdata ne '' ? $uzdata : $zdata );
    }
    else {
        my @NEEDEDZONES = split( /\,/, ( $dataref->{'zones'} || $dataref->{'zone'} ) );
        my $count = 0;
        my $zonedata;
        foreach my $zone (@NEEDEDZONES) {
            $count++;
            $zonedata = $self->{'publicapi'}->getzone_local( $zone, $unique_dns_request_id . '_' . $count );
            $self->output('cpdnszone-' . Cpanel::Encoder::URI::uri_encode_str($zone) . '=' . Cpanel::Encoder::URI::uri_encode_str($zonedata) . '&' );
        }
    }
    return $self->_check_action( "get the zones " . ( $dataref->{'zones'} || $dataref->{'zone'} ), $Cpanel::NameServer::Constants::DO_NOT_QUEUE );
}

# Create a method to list all of the zones on the system.
sub getzonelist {
    my ( $self, $unique_dns_request_id, $dataref, $rawdata ) = @_;
    my @ZONES = $self->{'publicapi'}->getzonelist_local($unique_dns_request_id);
    my @check_action_results = $self->_check_action( "get the zone list", $Cpanel::NameServer::Constants::DO_NOT_QUEUE );
    return (@check_action_results) if $check_action_results[$Cpanel::NameServer::Constants::CHECK_ACTION_POSITION_STATUS] != $Cpanel::NameServer::Constants::SUCCESS;
    foreach my $zone (@ZONES) {
        if ( Cpanel::StringFunc::Match::endmatch( $zone, '.db' ) ) {
            my $cleanzone = $zone;
            $cleanzone =~ Cpanel::StringFunc::Trim::endtrim( $cleanzone, '.db' );
            $self->output( $cleanzone . "\n" );
        }
        elsif ( !Cpanel::StringFunc::Match::beginmatch( $zone, '.' ) && $zone !~ /\.\./ ) {
            $self->output( $zone . "\n" );
        }
    }
    return ( $Cpanel::NameServer::Constants::SUCCESS, 'OK' );
}

# Create a method to check whether a zone exists.
sub zoneexists {
    my ( $self, $unique_dns_request_id, $dataref, $rawdata ) = @_;
    chomp( $dataref->{'zone'} );
    $self->output( $self->{'publicapi'}->zoneexists_local( $dataref->{'zone'}, $unique_dns_request_id ) ? '1' : '0' );
    return $self->_check_action( "determine if the zone $dataref->{'zone'} exists", $Cpanel::NameServer::Constants::DO_NOT_QUEUE );
}

# Create a method to list the nameserver records' IP addresses.
sub getips {
    my ( $self, $unique_dns_request_id, $dataref, $rawdata ) = @_;
    $self->output( $self->{'publicapi'}->getips_local($unique_dns_request_id) );
    return $self->_check_action( "receive an ips list", $Cpanel::NameServer::Constants::DO_NOT_QUEUE );
}

# Create a method that lists the nodes with which the current node is peered.
sub getpath {
    my ( $self, $unique_dns_request_id, $dataref, $rawdata ) = @_;
    $self->output( $self->{'publicapi'}->getpath_local($unique_dns_request_id) . "\n" );
    return $self->_check_action( "getpath", $Cpanel::NameServer::Constants::DO_NOT_QUEUE );
}

# Create a method that gets a module's version number.
sub version {
    my ( $self, $unique_dns_request_id, $dataref, $rawdata ) = @_;
    my $version = $self->{'publicapi'}->version();
    $self->{'error'} = $self->{'publicapi'}->{'error'} if $self->{'publicapi'}->{'error'};
    return $version;
}

1;

The following example code creates the MyRemoteModule server type:

# Package the module.
package Cpanel::NameServer::Remote::MyRemoteModule;

# Add use statements.
use strict;
use cPanel::PublicAPI                     ();
use cPanel::PublicAPI::WHM                ();
use cPanel::PublicAPI::WHM::DNS           ();
use cPanel::PublicAPI::WHM::CachedVersion ();
use Cpanel::Encoder::URI                  ();
use Cpanel::StringFunc::Match             ();
use Cpanel::StringFunc::Trim              ();
use Cpanel::NameServer::Remote            ();

our @ISA = ('Cpanel::NameServer::Remote');
our $VERSION = '1.2';


# Use the new() method to create a new LiveAPI object.
sub new {
    my $self = shift;
    my %OPTS = @_;
    $self = {%OPTS};
    bless $self;

    my $dnspeer        = $OPTS{'host'};
    my $user           = $OPTS{'user'};
    my $ip             = $OPTS{'ip'};
    my $pass           = $OPTS{'accesshash'} || $OPTS{'pass'};
    my $remote_timeout = $OPTS{'timeout'};

    $self->{'name'}            = $dnspeer;
    $self->{'update_type'}     = $OPTS{'update_type'};
    $self->{'local_timeout'}   = $OPTS{'local_timeout'};
    $self->{'remote_timeout'}  = $OPTS{'remote_timeout'};
    $self->{'queue_callback'}  = $OPTS{'queue_callback'};
    $self->{'output_callback'} = $OPTS{'output_callback'};

    $self->{'publicapi'} = cPanel::PublicAPI->new(
        'host'       => $dnspeer,
        'user'       => $user,
        'keepalive'  => 1,
        'accesshash' => $pass,
        'debug'      => ( $OPTS{'debug'} || 0 ),
        'usessl'     => 1,
        'timeout'    => $remote_timeout,
        ( $ip ? ( 'ip' => $ip ) : () )
    );

    return $self;
}


# Create the getallzones command method.
sub getallzones {
    my ( $self, $unique_dns_request_id, $dataref, $rawdata ) = @_;
    require Cpanel::Gzip::ungzip;
    my $zdata  = $self->{'publicapi'}->getallzones_local($unique_dns_request_id);
    my $uzdata = Cpanel::Gzip::ungzip::gunzipmem($zdata);
    $self->output( $uzdata ne '' ? $uzdata : $zdata );
    return $self->_check_action( 'get all the zones', $Cpanel::NameServer::Constants::DO_NOT_QUEUE );
}


# Create the cleandns method, to remove unnecessary zones.
sub cleandns {
    my ( $self, $unique_dns_request_id, $dataref, $rawdata ) = @_;
    $self->output( $self->{'publicapi'}->cleandns_local($unique_dns_request_id) );
    return $self->_check_action( 'cleanup dns', $Cpanel::NameServer::Constants::DO_NOT_QUEUE );
}


# Create a method to remove a single zone.
sub removezone {
    my ( $self, $unique_dns_request_id, $dataref, $rawdata ) = @_;
    chomp( $dataref->{'zone'} );
    $self->output( $self->{'publicapi'}->removezone_local( $dataref->{'zone'}, $unique_dns_request_id ) . "\n" );
    return $self->_check_action( "remove the zone: $dataref->{'zone'}", $Cpanel::NameServer::Constants::QUEUE );
}


# Create a method to remove multiple zones.
sub removezones {
    my ( $self, $unique_dns_request_id, $dataref, $rawdata ) = @_;
    chomp( $dataref->{'zone'} );
    chomp( $dataref->{'zones'} );
    if ( isatleastversion( '11.24.2', $self->{'publicapi'}->cached_version() ) ) {
        $self->output( $self->{'publicapi'}->removezones_local( ( $dataref->{'zones'} || $dataref->{'zone'} ), $unique_dns_request_id ) . "\n" );
    }
    else {
        my $count = 0;
        foreach my $zone ( split( /\,/, ( $dataref->{'zones'} || $dataref->{'zone'} ) ) ) {
            $count++;
            $zone =~ s/^\s*|\s*$//g;
            print $self->{'publicapi'}->removezone_local( $zone, $unique_dns_request_id . '_' . $count ) . "\n";
            {
                my @check_action_results = $self->_check_action( "remove the zone(s): " . ( $dataref->{'zones'} || $dataref->{'zone'} ), $Cpanel::NameServer::Constants::QUEUE );
                return (@check_action_results) if $check_action_results[$Cpanel::NameServer::Constants::CHECK_ACTION_POSITION_IS_RECOVERABLE_ERROR];
            }
        }
    }
    return $self->_check_action( "remove the zone(s): " . ( $dataref->{'zones'} || $dataref->{'zone'} ), $Cpanel::NameServer::Constants::QUEUE );
}


# Create a method to force BIND to reload all zones.
sub reloadbind {
    my ( $self, $unique_dns_request_id, $dataref, $rawdata ) = @_;
    chomp( $dataref->{'zone'} );
    $self->output( $self->{'publicapi'}->reloadbind_local( $unique_dns_request_id, $dataref->{'zone'} ) . "\n" );
    return $self->_check_action( "reload bind", $Cpanel::NameServer::Constants::QUEUE );
}


# Create a method to force BIND to reload specific zones.
sub reloadzones {
    my ( $self, $unique_dns_request_id, $dataref, $rawdata ) = @_;
    chomp( $dataref->{'zone'} );
    if ( isatleastversion( '11.23.2', $self->{'publicapi'}->cached_version() ) ) {
        $self->output( $self->{'publicapi'}->reloadzones_local( $unique_dns_request_id, $dataref->{'zone'} ) . "\n" );
        {
            my @check_action_results = $self->_check_action( "reload zones $dataref->{'zone'}", $Cpanel::NameServer::Constants::QUEUE );
            return (@check_action_results) if $check_action_results[$Cpanel::NameServer::Constants::CHECK_ACTION_POSITION_STATUS] != $Cpanel::NameServer::Constants::SUCCESS;
        }
    }
    else {
        $self->output( $self->{'publicapi'}->reloadbind_local($unique_dns_request_id) . "\n" );
        {
            my @check_action_results = $self->_check_action( "reload bind", $Cpanel::NameServer::Constants::QUEUE );
            return (@check_action_results) if $check_action_results[$Cpanel::NameServer::Constants::CHECK_ACTION_POSITION_STATUS] != $Cpanel::NameServer::Constants::SUCCESS;
        }
    }
    return ( $Cpanel::NameServer::Constants::SUCCESS, 'OK' );
}

# Create a method to force BIND to reload configuration files.
sub reconfigbind {
    my ( $self, $unique_dns_request_id, $dataref, $rawdata ) = @_;
    if ( isatleastversion( '10.0.0', $self->{'publicapi'}->cached_version() ) ) {
        $self->output( $self->{'publicapi'}->reconfigbind_local($unique_dns_request_id) . "\n" );
    }
    else {
        $self->output( $self->{'publicapi'}->reloadbind_local( $unique_dns_request_id, $dataref->{'zone'} ) . "\n" );
    }
    return $self->_check_action( "reconfig bind", $Cpanel::NameServer::Constants::QUEUE );
}


# Create a method to save new records to existing zone files.
sub savezone {
    my ( $self, $unique_dns_request_id, $dataref, $rawdata ) = @_;
    chomp( $dataref->{'zone'} );
    $self->output( $self->{'publicapi'}->savezone_local( $dataref->{'zone'}, $dataref->{'zonedata'}, $unique_dns_request_id ) );
    return $self->_check_action( "save the zone $dataref->{'zone'}", $Cpanel::NameServer::Constants::QUEUE );
}


# Create a method to add multiple zones to a remote system and the config database.
sub synczones {
    my ( $self, $unique_dns_request_id, $dataref, $rawdata ) = @_;
    chomp( $dataref->{'zone'} );
    $rawdata =~ s/^dnsuniqid=[^\&]+\&//g;
    $rawdata =~ s/\&dnsuniqid=[^\&]+//g;
    local $self->{'publicapi'}->{'timeout'} = ( ( int( $self->{'local_timeout'} / 2 ) > $self->{'remote_timeout'} ) ? int( $self->{'local_timeout'} / 2 ) : $self->{'remote_timeout'} );
    $self->output( $self->{'publicapi'}->synczones_local( $rawdata, $unique_dns_request_id ) );
    return $self->_check_action( "sync zones: $dataref->{'zone'}", $Cpanel::NameServer::Constants::QUEUE );
}

# Create a method that adds a new zone to the system and saves its contents.
sub quickzoneadd {
    my ( $self, $unique_dns_request_id, $dataref, $rawdata ) = @_;
    if ( isatleastversion( '11.24.4', $self->{'publicapi'}->cached_version() ) ) {
        $self->output( $self->{'publicapi'}->quickzoneadd_local( $dataref->{'zone'}, $dataref->{'zonedata'}, $unique_dns_request_id ) );
    }
    else {
        if ( isatleastversion( '11.24.2', $self->{'publicapi'}->cached_version() ) ) {
            $self->output(
                $self->{'publicapi'}->synczones_local(
                'cpdnszone-' . Cpanel::Encoder::URI::uri_encode_str($dataref->{'zone'}) .
                '=' .
                Cpanel::Encoder::URI::uri_encode_str($dataref->{'zonedata'}) .
                '&',
                $unique_dns_request_id . '_1'
                )
            );
        }
        else {
            $self->output( $self->{'publicapi'}->addzoneconf_local( $dataref->{'zone'}, $unique_dns_request_id . '_1' ) );
            $self->output( $self->{'publicapi'}->savezone_local( $dataref->{'zone'}, $dataref->{'zonedata'}, $unique_dns_request_id . '_2' ) ) unless ( $self->{'publicapi'}->{'error'} ne '' );
        }
        $self->output( $self->{'publicapi'}->reconfigbind_local( $unique_dns_request_id . '_3' ) ) unless ( $self->{'publicapi'}->{'error'} ne '' );
    }
    return $self->_check_action( "quick add the zone $dataref->{'zone'}", $Cpanel::NameServer::Constants::QUEUE );
}

# Create a method to add a zone to the configuration database.
sub addzoneconf {
    my ( $self, $unique_dns_request_id, $dataref, $rawdata ) = @_;
    chomp( $dataref->{'zone'} );
    $self->output( $self->{'publicapi'}->addzoneconf_local( $dataref->{'zone'}, $unique_dns_request_id ) );
    return $self->_check_action( "add the zone $dataref->{'zone'}", $Cpanel::NameServer::Constants::QUEUE );
}

# Create a method to get the contents of a single zone file.
sub getzone {
    my ( $self, $unique_dns_request_id, $dataref, $rawdata ) = @_;
    chomp( $dataref->{'zone'} );
    $self->output( $self->{'publicapi'}->getzone_local( $dataref->{'zone'}, $unique_dns_request_id ) );
    return $self->_check_action( "get the zone $dataref->{'zone'}", $Cpanel::NameServer::Constants::DO_NOT_QUEUE );
}

# Create a method to get the contents of multiple zone files.
sub getzones {
    my ( $self, $unique_dns_request_id, $dataref, $rawdata ) = @_;
    chomp( $dataref->{'zone'} );
    chomp( $dataref->{'zones'} );
    require Cpanel::Gzip::ungzip;
    if ( isatleastversion( '11.1.0', $self->{'publicapi'}->cached_version() ) ) {
        my $zdata = $self->{'publicapi'}->getzones_local( ( $dataref->{'zones'} || $dataref->{'zone'} ), $unique_dns_request_id );
        my $uzdata = Cpanel::Gzip::ungzip::gunzipmem($zdata);
        $self->output( $uzdata ne '' ? $uzdata : $zdata );
    }
    else {
        my @NEEDEDZONES = split( /\,/, ( $dataref->{'zones'} || $dataref->{'zone'} ) );
        my $count = 0;
        my $zonedata;
        foreach my $zone (@NEEDEDZONES) {
            $count++;
            $zonedata = $self->{'publicapi'}->getzone_local( $zone, $unique_dns_request_id . '_' . $count );
            $self->output('cpdnszone-' . Cpanel::Encoder::URI::uri_encode_str($zone) . '=' . Cpanel::Encoder::URI::uri_encode_str($zonedata) . '&' );
        }
    }
    return $self->_check_action( "get the zones " . ( $dataref->{'zones'} || $dataref->{'zone'} ), $Cpanel::NameServer::Constants::DO_NOT_QUEUE );
}

# Create a method to list all of the zones on the system.
sub getzonelist {
    my ( $self, $unique_dns_request_id, $dataref, $rawdata ) = @_;
    my @ZONES = $self->{'publicapi'}->getzonelist_local($unique_dns_request_id);
    my @check_action_results = $self->_check_action( "get the zone list", $Cpanel::NameServer::Constants::DO_NOT_QUEUE );
    return (@check_action_results) if $check_action_results[$Cpanel::NameServer::Constants::CHECK_ACTION_POSITION_STATUS] != $Cpanel::NameServer::Constants::SUCCESS;
    foreach my $zone (@ZONES) {
        if ( Cpanel::StringFunc::Match::endmatch( $zone, '.db' ) ) {
            my $cleanzone = $zone;
            $cleanzone =~ Cpanel::StringFunc::Trim::endtrim( $cleanzone, '.db' );
            $self->output( $cleanzone . "\n" );
        }
        elsif ( !Cpanel::StringFunc::Match::beginmatch( $zone, '.' ) && $zone !~ /\.\./ ) {
            $self->output( $zone . "\n" );
        }
    }
    return ( $Cpanel::NameServer::Constants::SUCCESS, 'OK' );
}

# Create a method to check whether a zone exists.
sub zoneexists {
    my ( $self, $unique_dns_request_id, $dataref, $rawdata ) = @_;
    chomp( $dataref->{'zone'} );
    $self->output( $self->{'publicapi'}->zoneexists_local( $dataref->{'zone'}, $unique_dns_request_id ) ? '1' : '0' );
    return $self->_check_action( "determine if the zone $dataref->{'zone'} exists", $Cpanel::NameServer::Constants::DO_NOT_QUEUE );
}

# Create a method to list the nameserver records' IP addresses.
sub getips {
    my ( $self, $unique_dns_request_id, $dataref, $rawdata ) = @_;
    $self->output( $self->{'publicapi'}->getips_local($unique_dns_request_id) );
    return $self->_check_action( "receive an ips list", $Cpanel::NameServer::Constants::DO_NOT_QUEUE );
}

# Create a method that lists the nodes with which the current node is peered.
sub getpath {
    my ( $self, $unique_dns_request_id, $dataref, $rawdata ) = @_;
    $self->output( $self->{'publicapi'}->getpath_local($unique_dns_request_id) . "\n" );
    return $self->_check_action( "getpath", $Cpanel::NameServer::Constants::DO_NOT_QUEUE );
}

# Create a method that gets a module's version number.
sub version {
    my ( $self, $unique_dns_request_id, $dataref, $rawdata ) = @_;
    my $version = $self->{'publicapi'}->version();
    $self->{'error'} = $self->{'publicapi'}->{'error'} if $self->{'publicapi'}->{'error'};
    return $version;
}

1;

The following example code creates the MyRemoteModule server type:

# Package the module.
package Cpanel::NameServer::Remote::MyRemoteModule;

# Add use statements.
use strict;
use Cpanel::PublicAPI                     ();
use Cpanel::PublicAPI::WHM                ();
use Cpanel::PublicAPI::WHM::DNS           ();
use Cpanel::PublicAPI::WHM::CachedVersion ();
use Cpanel::Encoder::URI                  ();
use Cpanel::StringFunc::Match             ();
use Cpanel::StringFunc::Trim              ();
use Cpanel::NameServer::Remote            ();

our @ISA = ('Cpanel::NameServer::Remote');
our $VERSION = '1.2';


# Use the new() method to create a new LiveAPI object.
sub new {
    my $self = shift;
    my %OPTS = @_;
    $self = {%OPTS};
    bless $self;

    my $dnspeer        = $OPTS{'host'};
    my $user           = $OPTS{'user'};
    my $ip             = $OPTS{'ip'};
    my $pass           = $OPTS{'accesshash'} || $OPTS{'pass'};
    my $remote_timeout = $OPTS{'timeout'};

    $self->{'name'}            = $dnspeer;
    $self->{'update_type'}     = $OPTS{'update_type'};
    $self->{'local_timeout'}   = $OPTS{'local_timeout'};
    $self->{'remote_timeout'}  = $OPTS{'remote_timeout'};
    $self->{'queue_callback'}  = $OPTS{'queue_callback'};
    $self->{'output_callback'} = $OPTS{'output_callback'};

    $self->{'publicapi'} = Cpanel::PublicAPI->new(
        'host'       => $dnspeer,
        'user'       => $user,
        'keepalive'  => 1,
        'accesshash' => $pass,
        'debug'      => ( $OPTS{'debug'} || 0 ),
        'usessl'     => 1,
        'timeout'    => $remote_timeout,
        ( $ip ? ( 'ip' => $ip ) : () )
    );

    return $self;
}


# Create the getallzones command method.
sub getallzones {
    my ( $self, $unique_dns_request_id, $dataref, $rawdata ) = @_;
    require Cpanel::Gzip::ungzip;
    my $zdata  = $self->{'publicapi'}->getallzones_local($unique_dns_request_id);
    my $uzdata = Cpanel::Gzip::ungzip::gunzipmem($zdata);
    $self->output( $uzdata ne '' ? $uzdata : $zdata );
    return $self->_check_action( 'get all the zones', $Cpanel::NameServer::Constants::DO_NOT_QUEUE );
}


# Create the cleandns method, to remove unnecessary zones.
sub cleandns {
    my ( $self, $unique_dns_request_id, $dataref, $rawdata ) = @_;
    $self->output( $self->{'publicapi'}->cleandns_local($unique_dns_request_id) );
    return $self->_check_action( 'cleanup dns', $Cpanel::NameServer::Constants::DO_NOT_QUEUE );
}


# Create a method to remove a single zone.
sub removezone {
    my ( $self, $unique_dns_request_id, $dataref, $rawdata ) = @_;
    chomp( $dataref->{'zone'} );
    $self->output( $self->{'publicapi'}->removezone_local( $dataref->{'zone'}, $unique_dns_request_id ) . "\n" );
    return $self->_check_action( "remove the zone: $dataref->{'zone'}", $Cpanel::NameServer::Constants::QUEUE );
}


# Create a method to remove multiple zones.
sub removezones {
    my ( $self, $unique_dns_request_id, $dataref, $rawdata ) = @_;
    chomp( $dataref->{'zone'} );
    chomp( $dataref->{'zones'} );
    if ( isatleastversion( '11.24.2', $self->{'publicapi'}->cached_version() ) ) {
        $self->output( $self->{'publicapi'}->removezones_local( ( $dataref->{'zones'} || $dataref->{'zone'} ), $unique_dns_request_id ) . "\n" );
    }
    else {
        my $count = 0;
        foreach my $zone ( split( /\,/, ( $dataref->{'zones'} || $dataref->{'zone'} ) ) ) {
            $count++;
            $zone =~ s/^\s*|\s*$//g;
            print $self->{'publicapi'}->removezone_local( $zone, $unique_dns_request_id . '_' . $count ) . "\n";
            {
                my @check_action_results = $self->_check_action( "remove the zone(s): " . ( $dataref->{'zones'} || $dataref->{'zone'} ), $Cpanel::NameServer::Constants::QUEUE );
                return (@check_action_results) if $check_action_results[$Cpanel::NameServer::Constants::CHECK_ACTION_POSITION_IS_RECOVERABLE_ERROR];
            }
        }
    }
    return $self->_check_action( "remove the zone(s): " . ( $dataref->{'zones'} || $dataref->{'zone'} ), $Cpanel::NameServer::Constants::QUEUE );
}


# Create a method to force BIND to reload all zones.
sub reloadbind {
    my ( $self, $unique_dns_request_id, $dataref, $rawdata ) = @_;
    chomp( $dataref->{'zone'} );
    $self->output( $self->{'publicapi'}->reloadbind_local( $unique_dns_request_id, $dataref->{'zone'} ) . "\n" );
    return $self->_check_action( "reload bind", $Cpanel::NameServer::Constants::QUEUE );
}


# Create a method to force BIND to reload specific zones.
sub reloadzones {
    my ( $self, $unique_dns_request_id, $dataref, $rawdata ) = @_;
    chomp( $dataref->{'zone'} );
    if ( isatleastversion( '11.23.2', $self->{'publicapi'}->cached_version() ) ) {
        $self->output( $self->{'publicapi'}->reloadzones_local( $unique_dns_request_id, $dataref->{'zone'} ) . "\n" );
        {
            my @check_action_results = $self->_check_action( "reload zones $dataref->{'zone'}", $Cpanel::NameServer::Constants::QUEUE );
            return (@check_action_results) if $check_action_results[$Cpanel::NameServer::Constants::CHECK_ACTION_POSITION_STATUS] != $Cpanel::NameServer::Constants::SUCCESS;
        }
    }
    else {
        $self->output( $self->{'publicapi'}->reloadbind_local($unique_dns_request_id) . "\n" );
        {
            my @check_action_results = $self->_check_action( "reload bind", $Cpanel::NameServer::Constants::QUEUE );
            return (@check_action_results) if $check_action_results[$Cpanel::NameServer::Constants::CHECK_ACTION_POSITION_STATUS] != $Cpanel::NameServer::Constants::SUCCESS;
        }
    }
    return ( $Cpanel::NameServer::Constants::SUCCESS, 'OK' );
}

# Create a method to force BIND to reload configuration files.
sub reconfigbind {
    my ( $self, $unique_dns_request_id, $dataref, $rawdata ) = @_;
    if ( isatleastversion( '10.0.0', $self->{'publicapi'}->cached_version() ) ) {
        $self->output( $self->{'publicapi'}->reconfigbind_local($unique_dns_request_id) . "\n" );
    }
    else {
        $self->output( $self->{'publicapi'}->reloadbind_local( $unique_dns_request_id, $dataref->{'zone'} ) . "\n" );
    }
    return $self->_check_action( "reconfig bind", $Cpanel::NameServer::Constants::QUEUE );
}


# Create a method to save new records to existing zone files.
sub savezone {
    my ( $self, $unique_dns_request_id, $dataref, $rawdata ) = @_;
    chomp( $dataref->{'zone'} );
    $self->output( $self->{'publicapi'}->savezone_local( $dataref->{'zone'}, $dataref->{'zonedata'}, $unique_dns_request_id ) );
    return $self->_check_action( "save the zone $dataref->{'zone'}", $Cpanel::NameServer::Constants::QUEUE );
}


# Create a method to add multiple zones to a remote system and the config database.
sub synczones {
    my ( $self, $unique_dns_request_id, $dataref, $rawdata ) = @_;
    chomp( $dataref->{'zone'} );
    $rawdata =~ s/^dnsuniqid=[^\&]+\&//g;
    $rawdata =~ s/\&dnsuniqid=[^\&]+//g;
    local $self->{'publicapi'}->{'timeout'} = ( ( int( $self->{'local_timeout'} / 2 ) > $self->{'remote_timeout'} ) ? int( $self->{'local_timeout'} / 2 ) : $self->{'remote_timeout'} );
    $self->output( $self->{'publicapi'}->synczones_local( $rawdata, $unique_dns_request_id ) );
    return $self->_check_action( "sync zones: $dataref->{'zone'}", $Cpanel::NameServer::Constants::QUEUE );
}

# Create a method that adds a new zone to the system and saves its contents.
sub quickzoneadd {
    my ( $self, $unique_dns_request_id, $dataref, $rawdata ) = @_;
    if ( isatleastversion( '11.24.4', $self->{'publicapi'}->cached_version() ) ) {
        $self->output( $self->{'publicapi'}->quickzoneadd_local( $dataref->{'zone'}, $dataref->{'zonedata'}, $unique_dns_request_id ) );
    }
    else {
        if ( isatleastversion( '11.24.2', $self->{'publicapi'}->cached_version() ) ) {
            $self->output(
                $self->{'publicapi'}->synczones_local(
                'cpdnszone-' . Cpanel::Encoder::URI::uri_encode_str($dataref->{'zone'}) .
                '=' .
                Cpanel::Encoder::URI::uri_encode_str($dataref->{'zonedata'}) .
                '&',
                $unique_dns_request_id . '_1'
                )
            );
        }
        else {
            $self->output( $self->{'publicapi'}->addzoneconf_local( $dataref->{'zone'}, $unique_dns_request_id . '_1' ) );
            $self->output( $self->{'publicapi'}->savezone_local( $dataref->{'zone'}, $dataref->{'zonedata'}, $unique_dns_request_id . '_2' ) ) unless ( $self->{'publicapi'}->{'error'} ne '' );
        }
        $self->output( $self->{'publicapi'}->reconfigbind_local( $unique_dns_request_id . '_3' ) ) unless ( $self->{'publicapi'}->{'error'} ne '' );
    }
    return $self->_check_action( "quick add the zone $dataref->{'zone'}", $Cpanel::NameServer::Constants::QUEUE );
}

# Create a method to add a zone to the configuration database.
sub addzoneconf {
    my ( $self, $unique_dns_request_id, $dataref, $rawdata ) = @_;
    chomp( $dataref->{'zone'} );
    $self->output( $self->{'publicapi'}->addzoneconf_local( $dataref->{'zone'}, $unique_dns_request_id ) );
    return $self->_check_action( "add the zone $dataref->{'zone'}", $Cpanel::NameServer::Constants::QUEUE );
}

# Create a method to get the contents of a single zone file.
sub getzone {
    my ( $self, $unique_dns_request_id, $dataref, $rawdata ) = @_;
    chomp( $dataref->{'zone'} );
    $self->output( $self->{'publicapi'}->getzone_local( $dataref->{'zone'}, $unique_dns_request_id ) );
    return $self->_check_action( "get the zone $dataref->{'zone'}", $Cpanel::NameServer::Constants::DO_NOT_QUEUE );
}

# Create a method to get the contents of multiple zone files.
sub getzones {
    my ( $self, $unique_dns_request_id, $dataref, $rawdata ) = @_;
    chomp( $dataref->{'zone'} );
    chomp( $dataref->{'zones'} );
    require Cpanel::Gzip::ungzip;
    if ( isatleastversion( '11.1.0', $self->{'publicapi'}->cached_version() ) ) {
        my $zdata = $self->{'publicapi'}->getzones_local( ( $dataref->{'zones'} || $dataref->{'zone'} ), $unique_dns_request_id );
        my $uzdata = Cpanel::Gzip::ungzip::gunzipmem($zdata);
        $self->output( $uzdata ne '' ? $uzdata : $zdata );
    }
    else {
        my @NEEDEDZONES = split( /\,/, ( $dataref->{'zones'} || $dataref->{'zone'} ) );
        my $count = 0;
        my $zonedata;
        foreach my $zone (@NEEDEDZONES) {
            $count++;
            $zonedata = $self->{'publicapi'}->getzone_local( $zone, $unique_dns_request_id . '_' . $count );
            $self->output('cpdnszone-' . Cpanel::Encoder::URI::uri_encode_str($zone) . '=' . Cpanel::Encoder::URI::uri_encode_str($zonedata) . '&' );
        }
    }
    return $self->_check_action( "get the zones " . ( $dataref->{'zones'} || $dataref->{'zone'} ), $Cpanel::NameServer::Constants::DO_NOT_QUEUE );
}

# Create a method to list all of the zones on the system.
sub getzonelist {
    my ( $self, $unique_dns_request_id, $dataref, $rawdata ) = @_;
    my @ZONES = $self->{'publicapi'}->getzonelist_local($unique_dns_request_id);
    my @check_action_results = $self->_check_action( "get the zone list", $Cpanel::NameServer::Constants::DO_NOT_QUEUE );
    return (@check_action_results) if $check_action_results[$Cpanel::NameServer::Constants::CHECK_ACTION_POSITION_STATUS] != $Cpanel::NameServer::Constants::SUCCESS;
    foreach my $zone (@ZONES) {
        if ( Cpanel::StringFunc::Match::endmatch( $zone, '.db' ) ) {
            my $cleanzone = $zone;
            $cleanzone =~ Cpanel::StringFunc::Trim::endtrim( $cleanzone, '.db' );
            $self->output( $cleanzone . "\n" );
        }
        elsif ( !Cpanel::StringFunc::Match::beginmatch( $zone, '.' ) && $zone !~ /\.\./ ) {
            $self->output( $zone . "\n" );
        }
    }
    return ( $Cpanel::NameServer::Constants::SUCCESS, 'OK' );
}

# Create a method to check whether a zone exists.
sub zoneexists {
    my ( $self, $unique_dns_request_id, $dataref, $rawdata ) = @_;
    chomp( $dataref->{'zone'} );
    $self->output( $self->{'publicapi'}->zoneexists_local( $dataref->{'zone'}, $unique_dns_request_id ) ? '1' : '0' );
    return $self->_check_action( "determine if the zone $dataref->{'zone'} exists", $Cpanel::NameServer::Constants::DO_NOT_QUEUE );
}

# Create a method to list the nameserver records' IP addresses.
sub getips {
    my ( $self, $unique_dns_request_id, $dataref, $rawdata ) = @_;
    $self->output( $self->{'publicapi'}->getips_local($unique_dns_request_id) );
    return $self->_check_action( "receive an ips list", $Cpanel::NameServer::Constants::DO_NOT_QUEUE );
}

# Create a method that lists the nodes with which the current node is peered.
sub getpath {
    my ( $self, $unique_dns_request_id, $dataref, $rawdata ) = @_;
    $self->output( $self->{'publicapi'}->getpath_local($unique_dns_request_id) . "\n" );
    return $self->_check_action( "getpath", $Cpanel::NameServer::Constants::DO_NOT_QUEUE );
}

# Create a method that gets a module's version number.
sub version {
    my ( $self, $unique_dns_request_id, $dataref, $rawdata ) = @_;
    my $version = $self->{'publicapi'}->version();
    $self->{'error'} = $self->{'publicapi'}->{'error'} if $self->{'publicapi'}->{'error'};
    return $version;
}

1;