Writing Remote Modules
For cPanel & WHM 11.30
Introduction
The dnsadmin plugin's remote module is responsible for communicating with other servers in your DNS cluster.
You must place the remote module in the
/usr/local/cpanel/Cpanel/NameServer/Remote/ directory, using
Cpanel::NameServer::Remote as the module's base class.
cPanel & WHM systems provide
Cpanel::PublicAPI as an HTTP client. The interfaces for both
cPanel::PublicAPI and
Cpanel::PublicAPI are the same. The package name is different to allow both to exist side-by-side on cPanel systems. Without
cPanel::PublicAPI, some of the features of this class cannot be used (such as the
_check_action subroutine).
How do I construct the object?
You must instantiate remote modules using a
new() method.
The following parameters are available for use in your script:
| Parameter |
Description |
| original_request_time |
The time the DNS command was made. |
| host |
The host to which the module will connect. |
| dnsrole |
The remote server's DNS role. |
| user |
The user specified in the DNS configuration file at /var/cpanel/cluster/$username/config/. |
| accesshash |
The password specified in the DNS configuration file at /var/cpanel/cluster/$username/config/. |
| local_timeout |
The amount of time to wait to send an HTTP request before the system will time out, in seconds. |
| remote_timeout |
The amount of time to wait to receive an HTTP request before the system will time out, in seconds. |
| update_type |
The type of update. |
| logger† |
The Cpanel::Logger instance. |
| queue_callback† |
A subroutine reference to the subroutine that manages queue requests. |
| output_callback† |
A subroutine reference that handles display data. |
| timeout |
The timeout to use. |
† — Required values that must be blessed in the final hash.
Command methods
You must implement each command passed to dnsadmin as a subroutine. This interface was designed for working with named configuration files and zones. For this reason, you will need to adjust some of the terminology.
Upon receiving a command, the dnsadmin process will call the subroutine for that command within your remote module. You can learn about
remote module commands below.
Parameters
The following parameters are used for each command:
my ( $self, $dnsuniqid, $dataref, $rawdata ) = @_;
| Parameter |
Description |
| dnsuniqid |
The command's unique identifier, used to ensure that the command is not sent to the same system twice. |
| dataref |
A hash reference that contains a serialized version of arguments passed to the command. |
| rawdata |
A hash reference that contains a raw URL version of the arguments passed to the system. |
Output and return values
The dnsadmin system returns data as output and parameters because the process is executed through output data. The output itself is implemented in the base class as the
output() subroutine. This subroutine relies on the
output_callback value that was blessed in the
new() subroutine.
Command methods are expected to return scalar arrays that contain 2 values:
status and
message.
status
status is a constant defined in
Cpanel::NameServers::Constants. The following values are valid for
status:
$Cpanel::NameServer::Constants::ERROR_INVALID_RESPONSE_LOGGED
$Cpanel::NameServer::Constants::ERROR_GENERIC
$Cpanel::NameServer::Constants::ERROR_TIMEOUT
$Cpanel::NameServer::Constants::ERROR_GENERIC_LOGGED
$Cpanel::NameServer::Constants::ERROR_TIMEOUT_LOGGED
$Cpanel::NameServer::Constants::SUCCESS
$Cpanel::NameServer::Constants::QUEUE
$Cpanel::NameServer::Constants::DO_NOT_QUEUE
message
The
message value should contain
OK or a human-readable error message.
Required command methods
getzonelist()
Get a list of all available zones on the system. This method should return a line-delimited list of available zones.
| Input |
None |
| Output |
A line-delimited list of the available zones. |
getzone()
Get the contents of a single zone file.
| Input |
{ 'zone' => 'The domain corresponding to the zone to fetch (e.g. example.com)' } |
| Output |
A BIND-compatible zone file. |
getzones()
Get the contents of multiple zone files.
| Input |
{ 'getzones' => 'A comma-separated list of domains corresponding to the zone files to fetch (e.g. example.com, example.net)' } |
| Output |
A URI-encoded, ampersand-delimited (&) list of zone files and their contents. The output should resemble the following: cpdnszone-$zone1=$zone1contents&$zone2=$zone2contents |
getallzones()
Get a complete dump of all of the zone files available on the system.
| Input |
None |
| Output |
A URI-encoded, ampersand-delimited (&) list of zone files and their contents. The output should resemble the following: cpdnszone-$zone1=$zone1contents&$zone2=$zone2contents |
removezone()
Remove a single zone from the system.
| Input |
{ 'zone' => 'The zone to remove (e.g. example.com.db)' } |
| Output |
An error message if it fails or 'zone' => 'deleted from $node' if it is successful. |
removezones()
Remove multiple zone files from the system.
| Input |
{ 'zone' => 'A comma-separated list of zones to remove (e.g. example.com.db,example.net.db)' } |
| Output |
An error message if it fails or 'zone' => 'deleted from $node' if it is successful. |
quickzoneadd()
Add a new zone to the system and save its contents.
Note: This method should be queued in case of non-fatal errors.
| Input |
{ 'zone' => 'The zone to add (e.g. example.com.db)' 'zonedata' => 'The contents to save in the new zone file' } |
| Output |
An error message if it fails or Zone $zone has been successfully added if it is successful. |
addzoneconf()
Add a zone to the configuration database (
named.conf on BIND servers).
Note: This method should be queued in case of non-fatal errors.
| Input |
{ 'zone' => 'The zone to add to the configuration database (e.g. example.com.db)' } |
| Output |
None |
savezone()
Save new records to an existing zone file. This will not add the zone file to the configuration database (
named.conf on BIND servers). This method will not produce any output.
Note: This method should be queued in case of non-fatal errors.
| Input |
{ 'zone' => 'The zone to modify (e.g. example.com.db)' 'zonedata' => 'The contents to add to the zone file' } |
| Output |
None |
synczones()
Add multiple zones to a remote system and to the configuration database (
named.conf on BIND servers).
Note: This method should be queued in case of non-fatal errors.
| Input |
{ 'cpdnszone-$zonename' => 'A URI-encoded version of the zone file to synchronize.' } |
| Output |
None |
zoneexists()
Find out whether a zone exists on the system.
| Input |
{ 'zone' => 'The zone to check' } |
| Output |
A boolean value of 1 or 0, where a value of 1 indicates that the zone exists on the system. |
getpath()
Get a list of nodes with which the current node is peered. This method is used to build the graph in WHM's
Configure Cluster feature (
Main >> Cluster/Remote Access >> Configure Cluster).
| Input |
None |
| Output |
A list of hosts and their corresponding nameservers (e.g. $host $nameservers) The $host should appear as it does in the node configuration file. The $nameservers variable should contain the remote nameservers as they are used in NS records. For example: host.example.com ns1.example.com host.example.com ns2.example.com |
version()
Get the version number of the module being used on the local system or on a remote system.
| Input |
None |
| Output |
The version number to display |
getips()
Get a list of the IP addresses used in the nameserver records.
| Input |
None |
| Output |
A line-delimited list of IP addresses used by the remote system. |
Optional command methods
Optional methods
must exist in your module; however, these methods do not have to do anything.
To implement an optional method, you can use the following boilerplate:
sub reconfigbind {
my ( $self, $unique_dns_request_id, $dataref, $rawdata ) = @_;
$self->output("No reload needed on $self->{'name'}\n");
return ( $Cpanel::NameServer::Constants::SUCCESS, 'OK' );
}
reloadbind()
Force BIND to reload.
| Input |
None |
| Output |
Anything |
reloadzones()
Force BIND to reload.
| Input |
None |
| Output |
Anything |
reconfigbind()
Force BIND to reload.
| Input |
None |
| Output |
Anything |
cleandns()
Remove unnecessary zones from the system.
| Input |
None |
| Output |
Anything |
The _check_action() subroutine
This subroutine is a way of returning proper data constants when sending information to, and receiving information from, dnsadmin. The subroutine checks the HTTP status of a remote system and determines whether an error is recoverable.
You can use the
_check_action() subroutine like so:
_check_action($msg, $Cpanel::NameServer::Constants::QUEUE);
or
_check_action($msg, $Cpanel::NameServer::Constants::DO_NOT_QUEUE);
QUEUE and
DO_NOT_QUEUE tell the overlying system whether it should queue the action if it fails.
You can use the
$msg string to specify what happened when the action was taken.
Notes and best practices
You may call one command subroutine from another. This is an acceptable practice; however, you should make sure to modify
dnsuniqid when this is done.
We recommend adding Perl's
_$int function to the end of the ID whenever you call one command subroutine from another.
Example
You can find an code examples in the
/usr/local/cpanel/Cpanel/NameServer/Remote/ directory.