• If you are still using CentOS 7.9, it's time to convert to Alma 8 with the free centos2alma tool by Plesk or Plesk Migrator. Please let us know your experiences or concerns in this thread:
    CentOS2Alma discussion

Retrieving Domains which have a primary nameserver zone

Yves Vogl

Basic Pleskian
Hi,

I'd like to retrieve a list of domains from a Plesk (9.0.1) server for synchronizing setup of a secondary dns.

Think of the environment as follows:

1. ns1.example.com is the master server
2. ns2.example.com is the secondary server


From ns2 I'd like to query via Plesk RPC ns1 (which is running the Plesk system) for any domains which have specified ns2 as one of their NS resource records. With this information I can build a configuration for the secondary.
 
Last edited:
It's done. Adjust configuration and run with proper rights via cron to retrieve all information for setting up a secondary dns (slave) with Bind:

Code:
#!/usr/bin/env ruby

require 'rubygems'
require 'net/https'
require 'builder'
require 'rexml/document'
require 'idn'
require 'erb'
require 'resolv'

SECONDARY_DNS_HOSTNAME = 'ns2.example.net'
ADMINISTRATOR_EMAIL    = '[email protected]'
BIND_ZONE_PATH         = '/usr/local/var/named'
BIND_SLAVE_CONFIG_PATH = '/usr/local/etc/named/named.slave.conf'
 
class PleskAgent

  CONFIG = {:hostname => 'plesk.example.com', :port => 8443, :username => 'admin', :password => 'secret'}  
  ROOTCA = '/etc/ssl/certs/ca-certificates.crt'
  PROTOCOL_VERSION = '1.6.0.1'
  
  attr_reader :username, :password, :http

  def self.dns_records 
    begin            
      data = self.request do |xml|   
        xml.dns do   
          xml.get_rec do
            xml.filter do
            end   
          end
        end          
      end           
    rescue Exception => e    
      PleskAgent.log_message e, :err
    end
  end  
  
  def initialize
    @username = CONFIG[:username]
    @password = CONFIG[:password]
    
    @http = Net::HTTP.new(CONFIG[:hostname], CONFIG[:port])
    @http.use_ssl = true
    if File.exists?(ROOTCA)
      @http.verify_mode = OpenSSL::SSL::VERIFY_PEER 
      @http.ca_file = ROOTCA
    else
      @http.verify_mode = OpenSSL::SSL::VERIFY_NONE
    end      
  end
  
  def send(request_xml)    
 
    request = request_xml.target!

    request_headers= {'Content-Type' => 'text/xml; charset=utf-8', 'HTTP_AUTH_LOGIN' => @username, 'HTTP_AUTH_PASSWD' => @password}

    PleskAgent.log_message "Establishing connection with #{CONFIG[:hostname]}"

    response = http.request_post('/enterprise/control/agent.php', request, request_headers)
    
    PleskAgent.log_message 'Processing response'
    
    response_xml = REXML::Document.new(response.body)

    status = response_xml.root.get_text('//status[1]')
    
    if status == 'ok'
      PleskAgent.log_message 'OK'
      response_xml.root
    else
      error_message = response_xml.root.get_text('//errtext[1]')
      error_code    = response_xml.root.get_text('//errcode[1]')
      PleskAgent.log_message "#{error_message} (#{error_code})"
      false
    end
  end

  def self.request
    rpc = self.new             
    xml = Builder::XmlMarkup.new
    xml.instruct! :xml, :version => '1.0' 
    xml.packet :version => PROTOCOL_VERSION do
      yield xml if block_given?
    end        
    rpc.send xml
  end

private

  def self.log_message(message)
    `logger -i -t PleskAgent "#{message}"`
  end
end

template = ERB.new <<-"EOF"

zone "<%= @zone %>" IN {
  type slave;
  file "#{BIND_ZONE_PATH}/<%= @zone %>.db";
  masters {#{Resolv.getaddress(PleskAgent::CONFIG[:hostname])};};
};
EOF

zones = "# Created at #{Time.now.utc}\r\n"

begin
  PleskAgent.dns_records.elements.collect('//result/data') do |record|
    if record.get_text('type') == 'NS' and record.get_text('value') == "#{SECONDARY_DNS_HOSTNAME}." 
      @zone = IDN::Idna.toASCII(record.get_text('host').to_s.chop)
      zones << template.result(binding)
    end 
  end
  
  PleskAgent.log_message 'Writing zones to file'
  `mv "#{BIND_SLAVE_CONFIG_PATH}" #{BIND_SLAVE_CONFIG_PATH}~`
  File.open(BIND_SLAVE_CONFIG_PATH, 'w') {|f| f.write(zones)}
  PleskAgent.log_message 'Done. Reloading Nameserver.'
  `rndc reload`
  
rescue Exception => e
  PleskAgent.log_message "#{e}. Restoring previous configuration and notifying administrator"
  `mv "#{BIND_SLAVE_CONFIG_PATH}~" #{BIND_SLAVE_CONFIG_PATH}`
  `echo "#{e}" | mail -s "Retrieval of zones for #{SECONDARY_DNS_HOSTNAME} failed" #{ADMINISTRATOR_EMAIL}`
end

Please keep mind… this will work but due to the given limitations it's not very elegant ;)
 
Last edited:
Back
Top