Автоматизация добавления домена в BIND9

Задался сегодня задачей автоматизации добавления доменов на сервер. Ведь надоедает вручную править файлы.

При написании скрипта все что можно было вынес в отдельные переменные, для того чтобы потом было легко их поменять.

Просто представлю вам скрипт(код в конце страницы). Он выводит содержимое нового конфигурационного файла зоны для BIND9 , остается просто добавить запись в named.conf.

Управляется скрипт параметрами коммадной строки.

Элементы в списках разделяются пробелом.

--ns          list     список NS-серверов                         (обязателен)

--ip          list     список IP, которые будут записаны          (обязателен)
                            как A-записи

--domain      Name     Зона, которую будет описывать файл         (обязателен)

--subdomains  list     список поддоменов, которые будут         (необязателен)
                          указывать на те же IP           

--mx          list     Список хостов на которые будут указывать (необязателен)
                            MX-записи домена .   

--email       email    email администратора домена               (необязателен)
                            если не указан, будет использован
                            стандартный master.DOMAIN.NAME            

Посмотрим как можно использовать данный скрипт:

$ ./domain --domain test.me --ns ns1.me.com ns2.me.com ns.example.com \
> --ip 1.1.1.1 2.2.2.2 3.3.3.3 12.12.12 \
> --subdomains www wiki www.wiki svn www.svn user www.test.of.user \
> --mx user.test.me mail.out.domain --email idler@instanceof.ru
$TTL    604800
@       IN      SOA     test.me. idler.instanceof.ru. (
                              1         ; Serial
                         604800         ; Refresh
                          86400         ; Retry
                        2419200         ; Expire
                         604800 )       ; Negative Cache TTL
;

        IN      NS      ns1.me.com.
        IN      NS      ns2.me.com.
        IN      NS      ns.example.com.


test.me.    14400   IN      MX      10  user.test.me.
test.me.    14400   IN      MX      20  mail.out.domain.


test.me.        14400   IN      A   1.1.1.1
test.me.        14400   IN      A   2.2.2.2
test.me.        14400   IN      A   3.3.3.3
test.me.        14400   IN      A   12.12.12


$ORIGIN test.me.

www     14400   IN      A       1.1.1.1
www     14400   IN      A       2.2.2.2
www     14400   IN      A       3.3.3.3
www     14400   IN      A       12.12.12

wiki     14400   IN      A       1.1.1.1
wiki     14400   IN      A       2.2.2.2
wiki     14400   IN      A       3.3.3.3
wiki     14400   IN      A       12.12.12

www.wiki     14400   IN      A       1.1.1.1
www.wiki     14400   IN      A       2.2.2.2
www.wiki     14400   IN      A       3.3.3.3
www.wiki     14400   IN      A       12.12.12

svn     14400   IN      A       1.1.1.1
svn     14400   IN      A       2.2.2.2
svn     14400   IN      A       3.3.3.3
svn     14400   IN      A       12.12.12

www.svn     14400   IN      A       1.1.1.1
www.svn     14400   IN      A       2.2.2.2
www.svn     14400   IN      A       3.3.3.3
www.svn     14400   IN      A       12.12.12

user     14400   IN      A       1.1.1.1
user     14400   IN      A       2.2.2.2
user     14400   IN      A       3.3.3.3
user     14400   IN      A       12.12.12

www.test.of.user     14400   IN      A       1.1.1.1
www.test.of.user     14400   IN      A       2.2.2.2
www.test.of.user     14400   IN      A       3.3.3.3
www.test.of.user     14400   IN      A       12.12.12

остается лишь добавить перенаправление в нужный файл в конце коммандной строки

Скрипт доступен через SVN под учетной записью guest с пустым паролем:

my@maximus:~$ svn --username guest cat https://svn.maxantonov.name:5050/utils/phputils/domain >domaingenerator
Password for 'guest':<ENTER>
my@maximus:~$ ls -l domaingenerator
-rw-r--r-- 1 my my 8107 2008-03-06 13:12 domaingenerator

А вот собственно код на сегодняшний день (2008-03-06)

#!/usr/bin/php
<?php
 
############################################################################
# Author: Max Antonov
# max at maxantonov dot name
############################################################################

 
class arrayFillException extends Exception{}
 
class arObject implements ArrayAccess,Iterator {
 
        protected $properties=array();
        protected $curKey;
 
        /**
         * numeric keys counter
         * @var int $listkey
         */
        protected $listkey=0;
 
        public function __construct(){
                $this->properties = array();
        }
 
 
        public function remove($key){
                 unset($this->properties[$key]);
        }
 
        public function count(){
            return count($this->properties);
        }
 
        public function fill($array){
            if(!is_array($array)){
                throw new arrayFillException('Not is array');
            }
            foreach($array as $key=>$val){
                $this->__set($key,$val);
            }
        }
 
 
    /************** Magic ****************/
        public function __get($key){
                return array_key_exists($key,$this->properties)?$this->properties[$key]:null;
        }
 
        public function __set($key,$value){
 
                if(strlen($key)===0){
                    $key = $this->listkey;
                    $this->listkey++;
                }
 
                return $this->properties[$key] = $value;
        }
 
 
    /***************** Implementation of ArrayAccess ***********/
 
    public function offsetExists ($offset){
        return array_key_exists($offset,$this->properties);//$this->properties);
    }
        public function offsetGet ($offset){
            return $this->__get($offset);
        }
        public function offsetSet ($offset, $value){
            return $this->__set($offset,$value);
        }
        public function offsetUnset ($offset){
            return $this->remove($offset);
        }
 
 
 
 
 
    public function current(){
                return isset($this->properties[$this->curKey])?$this->__get($this->curKey):false;
        }
 
        public function key(){
 
         return $this->curKey;
        }
 
        public function next(){
 
        if(!is_null(next($this->properties))){
            $this->curKey = key($this->properties);
        }
         return $this->current();
        }
        public function rewind(){
                        reset($this->properties);
                        $this->curKey = key($this->properties);
        }
        public function valid(){
 
                return isset($this->properties[$this->curKey]);
        }
 
        public function __call($name,$args){
 
            if(count($args)===0){
                return $this->__get($name);
            }
 
            if(count($args)===1){
                return $this->__set($name,$args[0]);
            }
        }
 
}
 
 
class optException extends Exception{}
 
 
class cliOption extends arObject{
 
    /**
     * Executable file name
     * @var string $program
     */
    private $program;
 
    /**
     * List of not prefixed with minus options
     * @var array $arglist
     */
    private $arglist;
 
    /**
     * Class constructor
     * @param array $argv Commandline Arguments
     */
    public function __construct($argv){
        $this->parse($argv);
    }
 
    /**
     * Rewrite set function - this make properties readonly
     */
    public function __set($key,$val){
        return false;
    }
    /**
     * Parse command line options
     */
    private function parse($argv){
        $this->program = array_shift($argv);
        while($this->parseNext($argv));
    }
 
 
    /**
     * Parse next one commandline option
     * and set self property in true if option without argument
     * or set value
     * @param array $argv Commandline Arguments
     */
    private function parseNext(&$argv){
        if(!is_array($argv) || count($argv)<1){
            return false;
        }
 
        $option = array_shift($argv);
 
        if(substr($option,0,2)==='--'){
 
            $option = substr($option,2);
            $this->properties[$option] = array();
            while(  count($argv)>0 && substr($argv[0],0,2)!='--'){
                $this->properties[$option][] = array_shift($argv);
            }
            if( count($argv)===0) return false;
            return true;
        }
 
        throw new optException('PARSE ERROR');
    }
 
 
    /**
     * Return name of running program
     * @return string name of program
     */
    public function getProgramName(){
        return $this->program;
    }
 
 
 
}
 
 
 
 
function usage(){
global $argv;
$prg=$argv[0];
$Revision="";
echo <<<USG
 
 
################################################################################
This programm is bind9 config generator writen by Max Antonov.
################################################################################
 
 
--------------------------------------------------------------------------------
USAGE:
{$prg} OPTIONS
--------------------------------------------------------------------------------
Available command line switches:
 
 
switch   |  argument | description                          | required/optional
--------------------------------------------------------------------------------
--ns          list     list of nameservers                         (required)
--ip          list     list of IPs, which writes in A-record       (required)
--domain      Name     name of domain, which will describes        (required)
 
--subdomains  list     list of subdomans, which A-records
                           will be point to the same IPs           (optional)
 
--mx          list     list of hostnames, where will point
                            MX-records of this domain.             (optional)
 
--email       email    email of domain administrator
                            if not present - will be write
                            standart master.DOMAIN.NAME            (optional)
 
Version$Revision: 31 $
################################################################################
 
 
 
 
USG;
    exit(0);
 
}
 
 
//----------------------- BEGIN  ----------------
 
try{
$options = new cliOption($argv);
}catch(optException $e){
    usage();
}
if(isset($options['help'])) usage();
 
$test= array(
    'ip',
    'domain',
    'ns'
);
 
foreach($test as $k){
    if(count($options[$k])<1){
        usage();
    }
}
 
 
$ip = $ns = $mx = array();
$mxText = $nsText = $ipText  = '';
//foreach($options->ip as $ipItem){ $ip[] = $ipItem;}
//foreach($options->ns as $nsItem){ $ns[] = $nsItem;}
 
//------ {{{ MX --------
if($options->offsetExists('mx')){
    if(count($options->mx)>0){
        $i=0;
        foreach($options->mx as $mxDomain){
            $i+=10;
            $mxText .= <<<MXTXT
{$options['domain'][0]}.    14400   IN      MX      {$i}  {$mxDomain}.
 
MXTXT;
        }
    }else{
$mxText = "{$options['domain'][0]}.    14400   IN      MX      10  {$options['domain'][0]}.";
    }
}
 
//------ MX }}} -------
 
//------ {{{ NS -----
 
 
foreach($options->ns as $nsImem){
    $nsText .= <<<NSTXT
        IN      NS      {$nsImem}.
 
NSTXT;
}
 
 
//------ NS }}} ------
 
 
//------ {{{ IP ------
 
foreach($options->ip as $ipItem){
$ipText .= <<<IPTXT
{$options['domain'][0]}.        14400   IN      A   {$ipItem}
 
IPTXT;
}
 
//------  IP }}} -----
 
 
//------ {{{ SubDomains ----
 
$subText = '';
 
if($options->offsetExists('subdomains') && count($options->subdomains)>0){
    $subText .= "\$ORIGIN {$options['domain'][0]}.\n\n";
    foreach($options->subdomains as $sub){
        foreach($options->ip as $IP){
$subText .= <<<SUBDOM
{$sub}     14400   IN      A       {$IP}
 
SUBDOM;
        }
 
        $subText .= "\n";
 
    }
 
}
/*
var_dump($options->subdomains);
echo $subText;*/
//------ SubDomains }}} ----
 
$email = ($options->offsetExists('email')&&count($options->email)>0)?str_replace('@','.',$options->email[0]):"master.".$options->domain[0];
 
$TEMPLATE = <<<TPL
\$TTL    604800
@       IN      SOA     {$options->domain[0]}. {$email}. (
                              1         ; Serial
                         604800         ; Refresh
                          86400         ; Retry
                        2419200         ; Expire
                         604800 )       ; Negative Cache TTL
;
 
{$nsText}
 
{$mxText}
 
{$ipText}
 
{$subText}
 
TPL;
 
    echo $TEMPLATE;
Последние изменения: %2010/%03/%22 %01:%Mar