Passage à Net::DNS
parent
0dc7cdea82
commit
e6da9f192e
|
@ -84,17 +84,17 @@ get '/' => sub {
|
||||||
|
|
||||||
prefix '/domain' => sub {
|
prefix '/domain' => sub {
|
||||||
|
|
||||||
any ['post', 'get'] => '/updateraw/:domain' => sub {
|
post '/updateraw/:domain' => sub {
|
||||||
what_is_next rt_dom_updateraw
|
what_is_next rt_dom_updateraw
|
||||||
get_session( qw/login passwd/ )
|
get_session( qw/login passwd/ )
|
||||||
, get_param( qw/domain zoneupdated/)
|
, get_param( qw/domain zoneupdated/)
|
||||||
, get_request( qw/address referer/ );
|
, get_request( qw/address referer/ );
|
||||||
};
|
};
|
||||||
|
|
||||||
any ['post', 'get'] => '/update/:domain' => sub {
|
post '/update/:domain' => sub {
|
||||||
what_is_next rt_dom_update
|
what_is_next rt_dom_update
|
||||||
get_session( qw/login passwd/ )
|
get_session( qw/login passwd/ )
|
||||||
, get_param( qw/type name value ttl priority domain/ );
|
, get_param( qw/domain name type priority rdata ttl/ );
|
||||||
};
|
};
|
||||||
|
|
||||||
get '/details/:domain' => sub {
|
get '/details/:domain' => sub {
|
||||||
|
@ -117,25 +117,26 @@ prefix '/domain' => sub {
|
||||||
, get_request( qw/address referer/ );
|
, get_request( qw/address referer/ );
|
||||||
};
|
};
|
||||||
|
|
||||||
get '/del/:domain/:name/:type/:host/:ttl' => sub {
|
get '/del/:domain/:name/:ttl/:type/:rdata' => sub {
|
||||||
what_is_next rt_dom_del_entry
|
what_is_next rt_dom_del_entry
|
||||||
get_session( qw/login passwd/ )
|
get_session( qw/login passwd/ )
|
||||||
, get_param( qw/domain name type host ttl/ )
|
, get_param( qw/domain name type ttl rdata/ )
|
||||||
, get_request( qw/address referer/ );
|
, get_request( qw/address referer/ );
|
||||||
};
|
};
|
||||||
|
|
||||||
get '/mod/:domain/:name/:type/:host/:ttl' => sub {
|
post '/mod/:domain' => sub {
|
||||||
what_is_next rt_dom_mod_entry
|
what_is_next rt_dom_mod_entry
|
||||||
get_session( qw/login passwd/ )
|
get_session( qw/login passwd/ )
|
||||||
, get_param( qw/type name ttl domain name type host ttl
|
, get_param( qw/domain
|
||||||
newpriority newtype newhost newname newttl / )
|
oldpriority oldtype oldname oldttl oldrdata
|
||||||
|
newpriority newtype newname newttl newrdata/ )
|
||||||
, get_request( qw/address referer/ );
|
, get_request( qw/address referer/ );
|
||||||
};
|
};
|
||||||
|
|
||||||
get '/cli/:login/:pass/:domain/:name/:type/:host/:ttl/:ip' => sub {
|
get '/cli/:login/:pass/:domain/:name/:type/:rdata/:ttl/:ip' => sub {
|
||||||
what_is_next rt_dom_cli_mod_entry
|
what_is_next rt_dom_cli_mod_entry
|
||||||
get_session( qw/login/ )
|
get_session( qw/login/ )
|
||||||
, get_param( qw/passwd domain name type host ttl ip/ );
|
, get_param( qw/passwd domain name type rdata ttl ip/ );
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
34
lib/app.pm
34
lib/app.pm
|
@ -70,7 +70,7 @@ sub is_owning_domain {
|
||||||
|
|
||||||
# DOMAIN
|
# DOMAIN
|
||||||
|
|
||||||
sub _get_zone {
|
sub get_zone {
|
||||||
my ($self, $domain) = @_;
|
my ($self, $domain) = @_;
|
||||||
|
|
||||||
# say "";
|
# say "";
|
||||||
|
@ -93,41 +93,13 @@ sub _get_zone {
|
||||||
sub add_domain {
|
sub add_domain {
|
||||||
my ($self, $login, $domain) = @_;
|
my ($self, $login, $domain) = @_;
|
||||||
$self->db->add_domain($login, $domain);
|
$self->db->add_domain($login, $domain);
|
||||||
$self->_get_zone($domain)->addzone()
|
$self->get_zone($domain)->addzone()
|
||||||
}
|
}
|
||||||
|
|
||||||
sub delete_domain {
|
sub delete_domain {
|
||||||
my ($self, $domain) = @_;
|
my ($self, $domain) = @_;
|
||||||
$self->db->delete_domain($domain);
|
$self->db->delete_domain($domain);
|
||||||
$self->_get_zone($domain)->del()
|
$self->get_zone($domain)->del()
|
||||||
}
|
|
||||||
|
|
||||||
sub modify_entry {
|
|
||||||
my ($self, $domain, $entryToModify, $newEntry) = @_;
|
|
||||||
my $zone = $self->_get_zone($domain)->modify_entry(
|
|
||||||
$entryToModify, $newEntry );
|
|
||||||
$self->update_domain($zone, $domain)
|
|
||||||
}
|
|
||||||
|
|
||||||
sub delete_entry {
|
|
||||||
my ($self, $domain, $entryToDelete) = @_;
|
|
||||||
my $zone = $self->_get_zone($domain)->delete_entry( $entryToDelete );
|
|
||||||
$self->update_domain($zone, $domain)
|
|
||||||
}
|
|
||||||
|
|
||||||
sub update_domain_raw {
|
|
||||||
my ($self, $zone, $domain) = @_;
|
|
||||||
$self->_get_zone($domain)->update_raw($zone)
|
|
||||||
}
|
|
||||||
|
|
||||||
sub update_domain {
|
|
||||||
my ($self, $zone, $domain) = @_;
|
|
||||||
$self->_get_zone($domain)->update($zone)
|
|
||||||
}
|
|
||||||
|
|
||||||
sub get_domain {
|
|
||||||
my ($self, $domain) = @_;
|
|
||||||
$self->_get_zone($domain)->get()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sub get_domains {
|
sub get_domains {
|
||||||
|
|
149
lib/rt/domain.pm
149
lib/rt/domain.pm
|
@ -52,20 +52,13 @@ sub rt_dom_cli_mod_entry {
|
||||||
return $res;
|
return $res;
|
||||||
}
|
}
|
||||||
|
|
||||||
$app->modify_entry( $$param{domain}
|
my $zone = $app->get_zone( $$param{domain} );
|
||||||
, {
|
my $zf = $zone->get_zonefile();
|
||||||
type => $$param{type}
|
$zf->rr_mod(
|
||||||
, name => $$param{name}
|
"$$param{name} $$param{ttl} $$param{type} $$param{rdata}"
|
||||||
, host => $$param{host}
|
, "$$param{name} $$param{ttl} $$param{type} $$param{ip}"
|
||||||
, ttl => $$param{ttl}
|
);
|
||||||
}
|
$zone->update( $zf );
|
||||||
, {
|
|
||||||
newtype => $$param{type}
|
|
||||||
, newname => $$param{name}
|
|
||||||
, newhost => $$param{ip}
|
|
||||||
, newttl => $$param{ttl}
|
|
||||||
, newpriority => ''
|
|
||||||
});
|
|
||||||
|
|
||||||
$app->disconnect();
|
$app->disconnect();
|
||||||
};
|
};
|
||||||
|
@ -88,12 +81,13 @@ sub rt_dom_mod_entry {
|
||||||
|
|
||||||
my @missingitems;
|
my @missingitems;
|
||||||
|
|
||||||
for(qw/type name ttl domain name type host ttl
|
for(qw/domain
|
||||||
newtype newhost newname newttl/) {
|
oldtype oldname oldrdata oldttl
|
||||||
|
newtype newname newrdata newttl/) {
|
||||||
push @missingitems, $_ unless($$param{$_});
|
push @missingitems, $_ unless($$param{$_});
|
||||||
}
|
}
|
||||||
|
|
||||||
if($$param{type} eq 'MX' && ! $$param{newpriority}) {
|
if($$param{oldtype} eq 'MX' && ! $$param{newpriority}) {
|
||||||
push @missingitems, "newpriority";
|
push @missingitems, "newpriority";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -102,8 +96,9 @@ sub rt_dom_mod_entry {
|
||||||
return $res;
|
return $res;
|
||||||
}
|
}
|
||||||
|
|
||||||
for(qw/type name ttl domain name type host ttl
|
for(qw/domain
|
||||||
newpriority newtype newhost newname newttl/) {
|
oldtype oldname oldrdata oldttl
|
||||||
|
newtype newname newrdata newttl/) {
|
||||||
say "$_ : $$param{$_}" if $$param{$_};
|
say "$_ : $$param{$_}" if $$param{$_};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -124,20 +119,23 @@ sub rt_dom_mod_entry {
|
||||||
return $res;
|
return $res;
|
||||||
}
|
}
|
||||||
|
|
||||||
$app->modify_entry( $$param{domain}
|
my $zone = $app->get_zone( $$param{domain} );
|
||||||
, {
|
my $zf = $zone->get_zonefile();
|
||||||
type => $$param{type}
|
my $str_old =
|
||||||
, name => $$param{name}
|
"$$param{oldname} $$param{oldttl} $$param{oldtype} $$param{oldrdata}";
|
||||||
, host => $$param{host}
|
my $str_new = "$$param{newname} $$param{newttl} $$param{newtype} ";
|
||||||
, ttl => $$param{ttl}
|
if($$param{newtype} eq "MX") {
|
||||||
}
|
$str_new .= "$$param{newpriority} $$param{newrdata}";
|
||||||
, {
|
}
|
||||||
newtype => $$param{newtype}
|
else {
|
||||||
, newname => $$param{newname}
|
$str_new .= "$$param{newrdata}";
|
||||||
, newhost => $$param{newhost}
|
}
|
||||||
, newttl => $$param{newttl}
|
|
||||||
, newpriority => $$param{newpriority}
|
say "old : $str_old";
|
||||||
});
|
say "new : $str_new";
|
||||||
|
$zf->rr_mod( $str_old, $str_new);
|
||||||
|
$zone->update( $zf );
|
||||||
|
|
||||||
$app->disconnect();
|
$app->disconnect();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -168,12 +166,13 @@ sub rt_dom_del_entry {
|
||||||
return $res;
|
return $res;
|
||||||
}
|
}
|
||||||
|
|
||||||
$app->delete_entry( $$param{domain}, {
|
my $zone = $app->get_zone( $$param{domain} );
|
||||||
type => $$param{type},
|
my $zf = $zone->get_zonefile();
|
||||||
name => $$param{name},
|
$zf->rr_del_raw(
|
||||||
host => $$param{host},
|
"$$param{name} $$param{ttl} $$param{type} $$param{rdata}"
|
||||||
ttl => $$param{ttl}
|
);
|
||||||
});
|
$zone->update( $zf );
|
||||||
|
|
||||||
$app->disconnect();
|
$app->disconnect();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -324,7 +323,8 @@ sub rt_dom_details {
|
||||||
return $res;
|
return $res;
|
||||||
}
|
}
|
||||||
|
|
||||||
my $zone = $app->get_domain($$param{domain});
|
my $zone = $app->get_zone( $$param{domain} );
|
||||||
|
my $zf = $zone->get_zonefile();
|
||||||
|
|
||||||
$app->disconnect();
|
$app->disconnect();
|
||||||
|
|
||||||
|
@ -333,7 +333,7 @@ sub rt_dom_details {
|
||||||
login => $$session{login}
|
login => $$session{login}
|
||||||
, admin => $$user{admin}
|
, admin => $$user{admin}
|
||||||
, domain => $$param{domain}
|
, domain => $$param{domain}
|
||||||
, domain_zone => $zone->output()
|
, domain_zone => $zf->dump()
|
||||||
, user_ip => $$request{address}
|
, user_ip => $$request{address}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -341,17 +341,7 @@ sub rt_dom_details {
|
||||||
$$res{params}{expert} = 1;
|
$$res{params}{expert} = 1;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
$$res{params}{a} = $zone->a();
|
$$res{params}{zone} = $zf->rr_array_to_array();
|
||||||
$$res{params}{aaaa} = $zone->aaaa();
|
|
||||||
$$res{params}{cname} = $zone->cname();
|
|
||||||
$$res{params}{ptr} = $zone->ptr();
|
|
||||||
$$res{params}{mx} = $zone->mx();
|
|
||||||
$$res{params}{ns} = $zone->ns();
|
|
||||||
|
|
||||||
for(qw/a aaaa cname ptr mx ns/) {
|
|
||||||
my $t = $_;
|
|
||||||
map { $$_{type} = uc $t } @{$$res{params}{$t}};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -378,7 +368,7 @@ sub rt_dom_update {
|
||||||
|
|
||||||
my @missingitems;
|
my @missingitems;
|
||||||
|
|
||||||
for(qw/type name value ttl domain/) {
|
for(qw/name ttl type rdata domain/) {
|
||||||
push @missingitems, $_ unless($$param{$_});
|
push @missingitems, $_ unless($$param{$_});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -403,34 +393,29 @@ sub rt_dom_update {
|
||||||
return $res;
|
return $res;
|
||||||
}
|
}
|
||||||
|
|
||||||
my $zone = $app->get_domain( $$param{domain} );
|
my $zone = $app->get_zone( $$param{domain} );
|
||||||
|
my $zf = $zone->get_zonefile();
|
||||||
|
|
||||||
# TODO better naming convention
|
my $name = $$param{name};
|
||||||
my $entries;
|
$name .= ".$$param{domain}" unless $name =~ /$$param{domain}$/;
|
||||||
for( $$param{type} ) {
|
my $str_new = "$name $$param{ttl} $$param{type} ";
|
||||||
if($_ eq 'A') { $entries = $zone->a }
|
|
||||||
elsif( $_ eq 'AAAA') { $entries = $zone->aaaa }
|
my $rdata = $$param{rdata};
|
||||||
elsif( $_ eq 'CNAME') { $entries = $zone->cname }
|
|
||||||
elsif( $_ eq 'MX') { $entries = $zone->mx }
|
if($$param{type} =~ /^(CNAME|MX|NS|PTR)$/ && $rdata !~ /\.$/) {
|
||||||
elsif( $_ eq 'PTR') { $entries = $zone->ptr }
|
$rdata .= ".$$param{domain}";
|
||||||
elsif( $_ eq 'NS') { $entries = $zone->ns }
|
|
||||||
elsif( $_ eq 'TXT') { $entries = $zone->txt } # TODO verify this
|
|
||||||
}
|
}
|
||||||
|
|
||||||
my $new_entry = {
|
if($$param{type} eq "MX") {
|
||||||
name => $$param{name}
|
$str_new .= "$$param{priority} $$param{rdata}";
|
||||||
, class => "IN"
|
}
|
||||||
, host => $$param{value}
|
else {
|
||||||
, ttl => $$param{ttl}
|
$str_new .= "$$param{rdata}";
|
||||||
, ORIGIN => $zone->origin
|
}
|
||||||
};
|
$zf->rr_add_raw($str_new);
|
||||||
|
$zf->new_serial();
|
||||||
|
$zone->update( $zf );
|
||||||
|
|
||||||
$$new_entry{priority} = $$param{priority} if $$param{type} eq 'MX';
|
|
||||||
push @$entries, $new_entry;
|
|
||||||
|
|
||||||
$zone->new_serial();
|
|
||||||
|
|
||||||
$app->update_domain( $zone , $$param{domain} );
|
|
||||||
$app->disconnect();
|
$app->disconnect();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -478,13 +463,9 @@ sub rt_dom_updateraw {
|
||||||
return $res;
|
return $res;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
my $success =
|
my $zone = $app->get_zone( $$param{domain} );
|
||||||
$app->update_domain_raw($$param{zoneupdated}, $$param{domain});
|
my $zf = $zone->update_raw( $$param{zoneupdated} );
|
||||||
|
$zone->update( $zf );
|
||||||
unless($success) {
|
|
||||||
$$res{deferred}{errmsg} = q{Problème de mise à jour du domaine.};
|
|
||||||
}
|
|
||||||
|
|
||||||
$$res{route} = '/domain/details/' . $$param{domain};
|
$$res{route} = '/domain/details/' . $$param{domain};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
101
lib/zone.pm
101
lib/zone.pm
|
@ -10,7 +10,7 @@ use getiface ':all';
|
||||||
use copycat ':all';
|
use copycat ':all';
|
||||||
use fileutil ':all';
|
use fileutil ':all';
|
||||||
use configuration ':all';
|
use configuration ':all';
|
||||||
use Data::Dump qw( dump );
|
#use Data::Dump qw( dump );
|
||||||
|
|
||||||
use zonefile;
|
use zonefile;
|
||||||
|
|
||||||
|
@ -86,103 +86,17 @@ sub get_remote_zf_ {
|
||||||
"$$self{dnsi}{mycfg}{zonedir}/$$self{domain}"
|
"$$self{dnsi}{mycfg}{zonedir}/$$self{domain}"
|
||||||
}
|
}
|
||||||
|
|
||||||
sub are_same_records_ {
|
|
||||||
my ($a, $b) = @_;
|
|
||||||
|
|
||||||
#debug({ a => $a });
|
|
||||||
#debug({ b => $b });
|
|
||||||
|
|
||||||
#$a->{priority} eq $b->{priority} &&
|
|
||||||
( $$a{name} eq $$b{name} &&
|
|
||||||
$$a{host} eq $$b{host} &&
|
|
||||||
$$a{ttl} == $$b{ttl} )
|
|
||||||
}
|
|
||||||
|
|
||||||
# returns the lists of domains of a certain type
|
|
||||||
sub get_records_ {
|
|
||||||
my ($zone, $entry) = @_;
|
|
||||||
|
|
||||||
for( lc $$entry{type} ) {
|
|
||||||
if ($_ eq 'a') { return $zone->a }
|
|
||||||
elsif ($_ eq 'aaaa') { return $zone->aaaa }
|
|
||||||
elsif ($_ eq 'cname') { return $zone->cname }
|
|
||||||
elsif ($_ eq 'ns') { return $zone->ns }
|
|
||||||
elsif ($_ eq 'mx') { return $zone->mx }
|
|
||||||
elsif ($_ eq 'ptr') { return $zone->ptr }
|
|
||||||
}
|
|
||||||
|
|
||||||
die 'Impossible to get the entry type.'
|
|
||||||
}
|
|
||||||
|
|
||||||
sub reload_secondary_dns_servers {
|
sub reload_secondary_dns_servers {
|
||||||
my $self = shift;
|
my $self = shift;
|
||||||
$_->reload_sec($$self{slavedzones}) for(@{$$self{dnsisec}})
|
$_->reload_sec($$self{slavedzones}) for(@{$$self{dnsisec}})
|
||||||
}
|
}
|
||||||
|
|
||||||
sub delete_entry {
|
sub get_zonefile {
|
||||||
my ($self, $entryToDelete) = @_;
|
|
||||||
|
|
||||||
my $zone = $self->get();
|
|
||||||
|
|
||||||
my $records = get_records_ $zone, $entryToDelete;
|
|
||||||
|
|
||||||
if( defined $records ) {
|
|
||||||
foreach my $i ( 0 .. scalar @{$records}-1 ) {
|
|
||||||
if(are_same_records_($records->[$i], $entryToDelete)) {
|
|
||||||
delete $records->[$i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$zone
|
|
||||||
}
|
|
||||||
|
|
||||||
sub modify_entry {
|
|
||||||
my ($self, $entryToModify, $newEntry) = @_;
|
|
||||||
|
|
||||||
my $zone = $self->get();
|
|
||||||
|
|
||||||
my $records = get_records_ $zone, $entryToModify;
|
|
||||||
|
|
||||||
if( defined $records ) {
|
|
||||||
|
|
||||||
foreach my $i ( 0 .. scalar @{$records}-1 ) {
|
|
||||||
|
|
||||||
if(are_same_records_($records->[$i], $entryToModify)) {
|
|
||||||
|
|
||||||
say "ENTRY TO MODIFY";
|
|
||||||
|
|
||||||
say $records->[$i]->{name} . ' = ' . $newEntry->{newname};
|
|
||||||
say $records->[$i]->{host} . ' = ' . $newEntry->{newhost};
|
|
||||||
say $records->[$i]->{ttl} . ' = ' . $newEntry->{newttl};
|
|
||||||
#say $records->[$i]->{type} . ' = ' . $newEntry->{newtype};
|
|
||||||
|
|
||||||
$records->[$i]->{name} = $newEntry->{newname};
|
|
||||||
$records->[$i]->{host} = $newEntry->{newhost};
|
|
||||||
$records->[$i]->{ttl} = $newEntry->{newttl};
|
|
||||||
#$records->[$i]->{type} = $newEntry->{newtype};
|
|
||||||
|
|
||||||
if( $$newEntry{newtype} eq 'MX' ) {
|
|
||||||
say
|
|
||||||
$records->[$i]->{priority}.' = '.$newEntry->{newpriority};
|
|
||||||
$records->[$i]->{priority} = $newEntry->{newpriority};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
dump($records);
|
|
||||||
|
|
||||||
$zone
|
|
||||||
}
|
|
||||||
|
|
||||||
sub get {
|
|
||||||
my $self = shift;
|
my $self = shift;
|
||||||
my $file = $self->get_remote_zf_();
|
my $file = $self->get_remote_zf_();
|
||||||
my $dest = $self->get_ztmp_file_();
|
my $dest = $self->get_ztmp_file_();
|
||||||
|
|
||||||
copycat ($file, $dest);
|
copycat ($file, $dest);
|
||||||
|
|
||||||
zonefile->new(domain => $$self{domain}, zonefile => $dest);
|
zonefile->new(domain => $$self{domain}, zonefile => $dest);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -212,7 +126,7 @@ sub addzone {
|
||||||
$zonefile->new_serial(); # update the serial number
|
$zonefile->new_serial(); # update the serial number
|
||||||
|
|
||||||
# write the new zone tmpfile to disk
|
# write the new zone tmpfile to disk
|
||||||
write_file $f->path, $zonefile->output();
|
write_file $f->path, $zonefile->dump();
|
||||||
|
|
||||||
my $file = $self->get_remote_zf_();
|
my $file = $self->get_remote_zf_();
|
||||||
copycat ($tmpfile, $file); # put the final zone on the server
|
copycat ($tmpfile, $file); # put the final zone on the server
|
||||||
|
@ -239,7 +153,7 @@ sub update {
|
||||||
my $tmpfile = $self->get_ztmp_file_();
|
my $tmpfile = $self->get_ztmp_file_();
|
||||||
|
|
||||||
# write the new zone tmpfile to disk
|
# write the new zone tmpfile to disk
|
||||||
write_file $tmpfile, $zonefile->output();
|
write_file $tmpfile, $zonefile->dump();
|
||||||
|
|
||||||
my $file = $self->get_remote_zf_();
|
my $file = $self->get_remote_zf_();
|
||||||
copycat ($tmpfile, $file); # put the final zone on the server
|
copycat ($tmpfile, $file); # put the final zone on the server
|
||||||
|
@ -258,11 +172,10 @@ sub update_raw {
|
||||||
my $zonefile;
|
my $zonefile;
|
||||||
my $file = $self->get_ztmp_file_();
|
my $file = $self->get_ztmp_file_();
|
||||||
|
|
||||||
# write the updated zone file to disk
|
# write the updated zone file to disk
|
||||||
write_file $file, $zonetext;
|
write_file $file, $zonetext;
|
||||||
|
|
||||||
eval { $zonefile = zonefile->new(zonefile => $file
|
eval { $zonefile = zonefile->new(zonefile => $file); };
|
||||||
, domain => $$self{domain}); };
|
|
||||||
|
|
||||||
if( $@ ) {
|
if( $@ ) {
|
||||||
unlink($file);
|
unlink($file);
|
||||||
|
@ -271,7 +184,7 @@ sub update_raw {
|
||||||
|
|
||||||
unlink($file);
|
unlink($file);
|
||||||
|
|
||||||
$self->update($zonefile)
|
$zonefile
|
||||||
}
|
}
|
||||||
|
|
||||||
sub del {
|
sub del {
|
||||||
|
|
186
lib/zonefile.pm
186
lib/zonefile.pm
|
@ -1,52 +1,180 @@
|
||||||
package zonefile;
|
package zonefile;
|
||||||
use v5.14;
|
use v5.14;
|
||||||
|
use Net::DNS::RR;
|
||||||
|
use Net::DNS::ZoneFile;
|
||||||
use Moo;
|
use Moo;
|
||||||
use DNS::ZoneParse;
|
use utf8;
|
||||||
|
use URI;
|
||||||
|
use Data::Dumper;
|
||||||
|
|
||||||
has zone => qw/is rw/ ;
|
has zone => qw/is rw/ ;
|
||||||
has [ qw/domain/ ] => qw/ is ro required 1/;
|
|
||||||
has [ qw/zonefile/ ] => qw/ is rw required 1/;
|
has [ qw/zonefile/ ] => qw/ is rw required 1/;
|
||||||
|
|
||||||
|
# Simple functions to manipulate lists of Net::DNS::RR
|
||||||
|
|
||||||
|
sub rr_array_del {
|
||||||
|
my ($zones, $rr) = @_;
|
||||||
|
my @z = grep { $_->plain ne $rr->plain } @$zones;
|
||||||
|
[ @z ]
|
||||||
|
}
|
||||||
|
|
||||||
|
sub rr_array_add {
|
||||||
|
my ($zone, $rr) = @_;
|
||||||
|
my @already_present = grep { $_->plain eq $rr->plain } @$zone;
|
||||||
|
push @$zone, $rr unless @already_present;
|
||||||
|
$zone
|
||||||
|
}
|
||||||
|
|
||||||
|
sub rr_array_new_serial {
|
||||||
|
my $zones = shift;
|
||||||
|
|
||||||
|
for(@{$zones}) {
|
||||||
|
if($_->type =~ /SOA/) {
|
||||||
|
my $serial = $_->serial;
|
||||||
|
$_->serial($serial + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$zones
|
||||||
|
}
|
||||||
|
|
||||||
|
sub rr_array_serial {
|
||||||
|
my $zones = shift;
|
||||||
|
|
||||||
|
for(@{$zones}) {
|
||||||
|
if($_->type =~ /SOA/) {
|
||||||
|
return $_->serial;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
die "Impossible to get the zone serial."
|
||||||
|
}
|
||||||
|
|
||||||
|
sub rr_array_dump {
|
||||||
|
my $zone = shift;
|
||||||
|
my $dump = '';
|
||||||
|
|
||||||
|
# write the SOA record first
|
||||||
|
for(@{$zone}) {
|
||||||
|
if($_->type =~ /SOA/i) {
|
||||||
|
$dump .= $_->string . "\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for(@{$zone}) {
|
||||||
|
if($_->type !~ /SOA/i) {
|
||||||
|
$dump .= $_->string . "\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$dump
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
sub BUILD {
|
sub BUILD {
|
||||||
my ($self) = @_;
|
my ($self) = @_;
|
||||||
|
|
||||||
my $filename = $$self{zonefile};
|
my $path = $$self{zonefile};
|
||||||
if($filename =~ "://")
|
|
||||||
{
|
|
||||||
my $fileuri = URI->new($filename);
|
|
||||||
$filename = $fileuri->path;
|
|
||||||
}
|
|
||||||
|
|
||||||
$$self{zone} = DNS::ZoneParse->new($filename, $$self{domain});
|
# zonefile is the filename
|
||||||
|
if($$self{zonefile} =~ "://") {
|
||||||
|
my $fileuri = URI->new($$self{zonefile});
|
||||||
|
$path = $fileuri->path;
|
||||||
|
}
|
||||||
|
|
||||||
|
my $zonefile = Net::DNS::ZoneFile->new( $path );
|
||||||
|
my @zone = $zonefile->read;
|
||||||
|
$$self{zone} = [ @zone ];
|
||||||
}
|
}
|
||||||
|
|
||||||
sub new_serial {
|
sub new_serial {
|
||||||
my $self = shift;
|
my $self = shift;
|
||||||
$self->zone->new_serial();
|
$$self{zone} = rr_array_new_serial $$self{zone}
|
||||||
}
|
|
||||||
|
|
||||||
sub origin {
|
|
||||||
my $self = shift;
|
|
||||||
$self->zone->origin();
|
|
||||||
}
|
|
||||||
|
|
||||||
sub output {
|
|
||||||
my $self = shift;
|
|
||||||
$self->zone->output();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sub dump {
|
sub dump {
|
||||||
my $self = shift;
|
my $self = shift;
|
||||||
$self->zone->dump();
|
rr_array_dump $$self{zone}
|
||||||
}
|
}
|
||||||
|
|
||||||
# better encapsulation
|
sub serial {
|
||||||
sub a { my $self = shift; $self->zone->a }
|
my ($self, $rr) = @_;
|
||||||
sub aaaa { my $self = shift; $self->zone->aaaa }
|
rr_array_serial $$self{zone}
|
||||||
sub cname { my $self = shift; $self->zone->cname }
|
}
|
||||||
sub ns { my $self = shift; $self->zone->ns }
|
|
||||||
sub mx { my $self = shift; $self->zone->mx }
|
# remove a raw line that represents the RR
|
||||||
sub ptr { my $self = shift; $self->zone->ptr }
|
sub rr_del_raw {
|
||||||
sub txt { my $self = shift; $self->zone->txt } # TODO TEST THIS
|
my ($self, $rrline) = @_;
|
||||||
|
my $rr = Net::DNS::RR->new($rrline);
|
||||||
|
$self->rr_del($rr)
|
||||||
|
}
|
||||||
|
|
||||||
|
sub rr_del {
|
||||||
|
my ($self, $rr) = @_;
|
||||||
|
$$self{zone} = rr_array_del $$self{zone}, $rr
|
||||||
|
}
|
||||||
|
|
||||||
|
# add a raw line that represents the RR
|
||||||
|
sub rr_add_raw {
|
||||||
|
my ($self, $rrline) = @_;
|
||||||
|
my $rr = Net::DNS::RR->new($rrline);
|
||||||
|
$self->rr_add($rr)
|
||||||
|
}
|
||||||
|
|
||||||
|
sub rr_add {
|
||||||
|
my ($self, $rr) = @_;
|
||||||
|
$$self{zone} = rr_array_add $$self{zone}, $rr
|
||||||
|
}
|
||||||
|
|
||||||
|
sub rr_mod {
|
||||||
|
my ($self, $rrline_old, $rrline_new) = @_;
|
||||||
|
$self->rr_del_raw($rrline_old);
|
||||||
|
$self->rr_add_raw($rrline_new);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
sub rr_array_to_array {
|
||||||
|
my ($self) = shift;
|
||||||
|
my $rr_list;
|
||||||
|
|
||||||
|
for(@{$$self{zone}}) {
|
||||||
|
|
||||||
|
my @list = split / /, $_->plain;
|
||||||
|
|
||||||
|
my $rr;
|
||||||
|
$$rr{name} = $list[0];
|
||||||
|
$$rr{ttl} = $list[1];
|
||||||
|
$$rr{class} = $list[2];
|
||||||
|
$$rr{type} = $list[3];
|
||||||
|
|
||||||
|
if($list[3] =~ /SOA/) {
|
||||||
|
$$rr{ns} = $list[4];
|
||||||
|
$$rr{postmaster} = $list[5];
|
||||||
|
$$rr{serial} = $list[6];
|
||||||
|
$$rr{refresh} = $list[7];
|
||||||
|
$$rr{retry} = $list[8];
|
||||||
|
$$rr{expire} = $list[9];
|
||||||
|
$$rr{minimum} = $list[10];
|
||||||
|
}
|
||||||
|
elsif($list[3] =~ /^(A(AAA)?|CNAME|NS)$/) {
|
||||||
|
$$rr{rdata} = $list[4];
|
||||||
|
}
|
||||||
|
elsif($list[3] =~ /^MX$/) {
|
||||||
|
$$rr{priority} = $list[4];
|
||||||
|
$$rr{rdata} = $list[5];
|
||||||
|
}
|
||||||
|
elsif($list[3] =~ /^TXT$/) {
|
||||||
|
$$rr{rdata} = $_->rdstring;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
die "This RR is not available : " . $_->plain;
|
||||||
|
}
|
||||||
|
|
||||||
|
push @$rr_list, $rr;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
$rr_list
|
||||||
|
}
|
||||||
|
|
||||||
1;
|
1;
|
||||||
|
|
|
@ -7,7 +7,7 @@ Ce qui permet d'être un remplaçant de DynDNS.
|
||||||
## Outils
|
## Outils
|
||||||
|
|
||||||
* [Dancer2](http://perldancer.org/)
|
* [Dancer2](http://perldancer.org/)
|
||||||
* [DNS::ZoneParse](https://metacpan.org/pod/DNS::ZoneParse)
|
* [Net::DNS](https://metacpan.org/pod/Net::DNS)
|
||||||
* [Bootstrap](http://twitter.github.io/bootstrap/)
|
* [Bootstrap](http://twitter.github.io/bootstrap/)
|
||||||
* [DBD::mysql](https://metacpan.org/module/DBD::mysql)
|
* [DBD::mysql](https://metacpan.org/module/DBD::mysql)
|
||||||
* [Moo](https://metacpan.org/pod/Moo)
|
* [Moo](https://metacpan.org/pod/Moo)
|
||||||
|
@ -17,6 +17,6 @@ Ce qui permet d'être un remplaçant de DynDNS.
|
||||||
|
|
||||||
* captcha
|
* captcha
|
||||||
* demander confirmation avant suppression d'une zone
|
* demander confirmation avant suppression d'une zone
|
||||||
* rajouter les types de RR manquants dans l'interface (remplacement de
|
* rajouter les types de RR manquants dans l'interface (amélioration)
|
||||||
DNS::ZoneParse, ou amélioration)
|
|
||||||
* déléguer les zones
|
* déléguer les zones
|
||||||
|
* revoir le script de màj automatique d'IP
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
use Test::More;
|
||||||
|
use Modern::Perl;
|
||||||
|
use lib 'lib';
|
||||||
|
use util ':all';
|
||||||
|
use zonefile;
|
||||||
|
|
||||||
|
chdir 'lib'; # TODO hack at 2am
|
||||||
|
|
||||||
|
#map {
|
||||||
|
# ok
|
||||||
|
# ( ( is_domain_name $_ ), "is '$_' a domain name" )
|
||||||
|
#} qw( foo.bar bar localhost. localhost );
|
||||||
|
#
|
||||||
|
#done_testing;
|
||||||
|
|
||||||
|
my $zf = zonefile->new( zonefile => "../t/zonefile.txt" );
|
||||||
|
$zf->new_serial();
|
||||||
|
print $zf->dump();
|
|
@ -0,0 +1,17 @@
|
||||||
|
$ORIGIN example.com. ; designates the start of this zone file in the namespace
|
||||||
|
$TTL 1h ; default expiration time of all resource records without their own TTL value
|
||||||
|
example.com. IN SOA ns.example.com. username.example.com. ( 2007120710 1d 2h 4w 1h )
|
||||||
|
example.com. IN NS ns ; ns.example.com is a nameserver for example.com
|
||||||
|
example.com. IN NS ns.somewhere.example. ; ns.somewhere.example is a backup nameserver for example.com
|
||||||
|
example.com. IN MX 10 mail.example.com. ; mail.example.com is the mailserver for example.com
|
||||||
|
@ IN MX 20 mail2.example.com. ; equivalent to above line, "@" represents zone origin
|
||||||
|
@ IN MX 50 mail3 ; equivalent to above line, but using a relative host name
|
||||||
|
example.com. IN A 192.0.2.1 ; IPv4 address for example.com
|
||||||
|
IN AAAA 2001:db8:10::1 ; IPv6 address for example.com
|
||||||
|
ns IN A 192.0.2.2 ; IPv4 address for ns.example.com
|
||||||
|
IN AAAA 2001:db8:10::2 ; IPv6 address for ns.example.com
|
||||||
|
www IN CNAME example.com. ; www.example.com is an alias for example.com
|
||||||
|
wwwtest IN CNAME www ; wwwtest.example.com is another alias for www.example.com
|
||||||
|
mail IN A 192.0.2.3 ; IPv4 address for mail.example.com
|
||||||
|
mail2 IN A 192.0.2.4 ; IPv4 address for mail2.example.com
|
||||||
|
mail3 IN A 192.0.2.5 ; IPv4 address for mail3.example.com
|
|
@ -17,7 +17,7 @@
|
||||||
|
|
||||||
<% FOREACH d IN alldomains %>
|
<% FOREACH d IN alldomains %>
|
||||||
<tr>
|
<tr>
|
||||||
<td><% d.domain %></td>
|
<td> <a href="/domain/details/<% d.domain %>/"><% d.domain %></a> </td>
|
||||||
<td><% d.login %></td>
|
<td><% d.login %></td>
|
||||||
|
|
||||||
<td>
|
<td>
|
||||||
|
|
133
views/details.tt
133
views/details.tt
|
@ -17,94 +17,70 @@
|
||||||
|
|
||||||
<table class="table" >
|
<table class="table" >
|
||||||
<caption>
|
<caption>
|
||||||
<td>Name</td>
|
<tr>
|
||||||
<td>Class</td>
|
<td>Domaine</td>
|
||||||
<td>Type</td>
|
<td>Type</td>
|
||||||
<td>Host</td>
|
<td>Cible</td>
|
||||||
<td>TTL</td>
|
<td>TTL</td>
|
||||||
|
</tr>
|
||||||
</caption>
|
</caption>
|
||||||
|
|
||||||
<% FOREACH address in ns %>
|
<% FOREACH rr in zone %>
|
||||||
<tr>
|
<tr>
|
||||||
<form action='/domain/mod/<%domain%>/<%address.name%>/NS/<%address.host%>/<%address.ttl%>'>
|
<% SWITCH rr.type %>
|
||||||
<td><input type='text' name='newname' class="form-control" value='<% address.name %>' /></td>
|
<% CASE [ "A", "AAAA", "TXT", "NS", "CNAME", "PTR" ] %>
|
||||||
<td><% address.class %></td>
|
|
||||||
<td><input type='text' name='newtype' class="form-control" value='<% address.type %>'/></td>
|
|
||||||
<td><input type='text' name='newhost' class="form-control" value='<% address.host %>'/></td>
|
|
||||||
<td><input type='number' name='newttl' class="form-control" value='<% address.ttl %>'/></td>
|
|
||||||
<td><input type='submit' id='submit' class="btn btn-success btn-xs" value='✔' />
|
|
||||||
</form>
|
|
||||||
<td><button type="button" class="btn btn-primary btn-danger btn-xs" onclick="location.href='http://'+location.host+'/domain/del/<% domain %>/<% address.name %>/NS/<% address.host %>/<% address.ttl %>';">✘</button></td>
|
|
||||||
</tr>
|
|
||||||
<% END %>
|
|
||||||
|
|
||||||
<% FOREACH address in a %>
|
<form method="post" action='/domain/mod/<% domain %>'>
|
||||||
<tr>
|
<input type="hidden" name="oldname" value="<% rr.name %>"/>
|
||||||
<form action='/domain/mod/<%domain%>/<%address.name%>/A/<%address.host%>/<%address.ttl%>'>
|
<input type="hidden" name="oldtype" value="<% rr.type %>"/>
|
||||||
<td><input type='text' name='newname' class="form-control" value='<% address.name %>'/></td>
|
<input type="hidden" name="oldttl" value="<% rr.ttl %>"/>
|
||||||
<td><% address.class %></td>
|
<input type="hidden" name="oldrdata" value="<% rr.rdata %>"/>
|
||||||
<td><input type='text' name='newtype' class="form-control" value='<% address.type %>'/></td>
|
|
||||||
<td><input type='text' name='newhost' class="form-control" value='<% address.host %>'/></td>
|
|
||||||
<td><input type='number' name='newttl' class="form-control" value='<% address.ttl %>'/></td>
|
|
||||||
<td><input type='submit' id='submit' class="btn btn-success btn-xs" value='✔' />
|
|
||||||
</form>
|
|
||||||
<td><button type="button" class="btn btn-primary btn-danger btn-xs" onclick="location.href='http://'+location.host+'/domain/del/<% domain %>/<% address.name %>/A/<% address.host %>/<% address.ttl %>';">✘</button></td>
|
|
||||||
</tr>
|
|
||||||
<% END %>
|
|
||||||
|
|
||||||
<% FOREACH address in aaaa %>
|
<td><input type='text' name='newname' class="form-control" value='<% rr.name %>'/></td>
|
||||||
<tr>
|
<td><% rr.class %></td>
|
||||||
<form action='/domain/mod/<%domain%>/<%address.name%>/AAAA/<%address.host%>/<%address.ttl%>'>
|
<td><input type='text' name='newtype' size='8' class="form-control" value='<% rr.type %>'/></td>
|
||||||
<td><input type='text' name='newname' class="form-control" value='<% address.name %>'/></td>
|
<td><input type='number' name='newttl' size='4' class="form-control" value='<% rr.ttl %>'/></td>
|
||||||
<td><% address.class %></td>
|
<td><input type='text' name='newrdata' class="form-control" value='<% rr.rdata %>'/></td>
|
||||||
<td><input type='text' name='newtype' class="form-control" value='<% address.type %>'/></td>
|
<td><input type='submit' id='submit' class="btn btn-success btn-xs" value='✔' /></td>
|
||||||
<td><input type='text' name='newhost' class="form-control" value='<% address.host %>'/></td>
|
|
||||||
<td><input type='number' name='newttl' class="form-control" value='<% address.ttl %>'/></td>
|
|
||||||
<td><input type='submit' id='submit' class="btn btn-success btn-xs" value='✔' />
|
|
||||||
</form>
|
|
||||||
<td><button type="button" class="btn btn-primary btn-danger btn-xs" onclick="location.href='http://'+location.host+'/domain/del/<% domain %>/<% address.name %>/AAAA/<% address.host %>/<% address.ttl %>';">✘</button></td>
|
|
||||||
</tr>
|
|
||||||
<% END %>
|
|
||||||
|
|
||||||
<% FOREACH address in cname %>
|
<td>
|
||||||
<tr>
|
<a href='/domain/del/<% domain %>/<% rr.name %>/<% rr.ttl %>/<% rr.type %>/<% rr.rdata %>'>
|
||||||
<form action='/domain/mod/<%domain%>/<%address.name%>/CNAME/<%address.host%>/<%address.ttl%>'>
|
<button type="button" class="btn btn-primary btn-danger btn-xs">
|
||||||
<td><input type='text' name='newname' class="form-control" value='<% address.name %>'/></td>
|
✘
|
||||||
<td><% address.class %></td>
|
</button>
|
||||||
<td><input type='text' name='newtype' class="form-control" value='<% address.type %>'/></td>
|
</a>
|
||||||
<td><input type='text' name='newhost' class="form-control" value='<% address.host %>'/></td>
|
</td>
|
||||||
<td><input type='number' name='newttl' class="form-control" value='<% address.ttl %>'/></td>
|
|
||||||
<td><input type='submit' id='submit' class="btn btn-success btn-xs" value='✔' />
|
|
||||||
</form>
|
</form>
|
||||||
<td><button type="button" class="btn btn-primary btn-danger btn-xs" onclick="location.href='http://'+location.host+'/domain/del/<% domain %>/<% address.name %>/CNAME/<% address.host %>/<% address.ttl %>';">✘</button></td>
|
|
||||||
</tr>
|
|
||||||
<% END %>
|
|
||||||
|
|
||||||
<% FOREACH address in ptr %>
|
<% CASE "MX" %>
|
||||||
<tr>
|
|
||||||
<form action='/domain/mod/<%domain%>/<%address.name%>/PTR/<%address.host%>/<%address.ttl%>'>
|
|
||||||
<td><input type='text' name='newname' class="form-control" value='<% address.name %>'/></td>
|
|
||||||
<td><% address.class %></td>
|
|
||||||
<td><input type='text' name='newtype' class="form-control" value='<% address.type %>'/></td>
|
|
||||||
<td><input type='text' name='newhost' class="form-control" value='<% address.host %>'/></td>
|
|
||||||
<td><input type='number' name='newttl' class="form-control" value='<% address.ttl %>'/></td>
|
|
||||||
<td><input type='submit' id='submit' class="btn btn-success btn-xs" value='✔' />
|
|
||||||
</form>
|
|
||||||
<td><button type="button" class="btn btn-primary btn-danger btn-xs" onclick="location.href='http://'+location.host+'/domain/del/<% domain %>/<% address.name %>/PTR/<% address.host %>/<% address.ttl %>';">✘</button></td>
|
|
||||||
</tr>
|
|
||||||
<% END %>
|
|
||||||
|
|
||||||
<% FOREACH address in mx %>
|
<form method="post" action='/domain/mod/<% domain %>'>
|
||||||
<tr>
|
<input type="hidden" name="oldname" value="<% rr.name %>"/>
|
||||||
<form action='/domain/mod/<%domain%>/<%address.name%>/MX/<%address.host%>/<%address.ttl%>'>
|
<input type="hidden" name="oldtype" value="<% rr.type %>"/>
|
||||||
<td><input type='text' name='newname' class="form-control" value='<% address.name %>'/></td>
|
<input type="hidden" name="oldttl" value="<% rr.ttl %>"/>
|
||||||
<td><% address.class %></td>
|
<input type="hidden" name="oldrdata" value="<% rr.rdata %>"/>
|
||||||
<td><input type='text' name='newtype' class="form-control" value='<% address.type %>'/></td>
|
<input type="hidden" name="oldpriority" value="<% rr.priority %>"/>
|
||||||
<td><input type='text' name='newhost' class="form-control" value='<% address.host %>'/><input type='number' name='newpriority' class="form-control" value='<%address.priority%>'/></td>
|
|
||||||
<td><input type='number' name='newttl' class="form-control" value='<% address.ttl %>'/></td>
|
<td><input type='text' name='newname' class="form-control" value='<% rr.name %>'/></td>
|
||||||
<td><input type='submit' id='submit' class="btn btn-success btn-xs" value='✔' />
|
<td><% rr.class %></td>
|
||||||
|
<td><input type='text' name='newtype' class="form-control" value='<% rr.type %>'/></td>
|
||||||
|
<td><input type='number' name='newttl' size='4' class="form-control" value='<% rr.ttl %>'/></td>
|
||||||
|
<td><input type='text' name='newrdata' class="form-control" value='<% rr.rdata %>'/>
|
||||||
|
<input type='number' name='newpriority' size='4' class="form-control" value='<% rr.priority %>'/></td>
|
||||||
|
<td><input type='submit' id='submit' class="btn btn-success btn-xs" value='✔' /></td>
|
||||||
|
|
||||||
|
<td>
|
||||||
|
<a href='/domain/del/<% domain %>/<% rr.name %>/<% rr.ttl %>/<% rr.type %>/<% rr.rdata %>'>
|
||||||
|
<button type="button" class="btn btn-primary btn-danger btn-xs">
|
||||||
|
✘
|
||||||
|
</button>
|
||||||
|
</a>
|
||||||
|
</td>
|
||||||
</form>
|
</form>
|
||||||
<td><button type="button" class="btn btn-primary btn-danger btn-xs" onclick="location.href='http://'+location.host+'/domain/del/<% domain %>/<% address.name %>/MX/<% address.host %>/<% address.ttl %>';">✘</button></td>
|
<% CASE %>
|
||||||
|
<td>Resource Record non pris en charge : <% rr.type %></td>
|
||||||
|
<% END %>
|
||||||
|
|
||||||
</tr>
|
</tr>
|
||||||
<% END %>
|
<% END %>
|
||||||
</table>
|
</table>
|
||||||
|
@ -134,6 +110,7 @@
|
||||||
<option value="MX">MX</option>
|
<option value="MX">MX</option>
|
||||||
<option value="NS">NS</option>
|
<option value="NS">NS</option>
|
||||||
<option value="PTR">PTR</option>
|
<option value="PTR">PTR</option>
|
||||||
|
<option value="TXT">TXT</option>
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
@ -147,9 +124,9 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="value" class="col-sm-2 control-label">Valeur</label>
|
<label for="rdata" class="col-sm-2 control-label">Valeur</label>
|
||||||
<div class="col-sm-3">
|
<div class="col-sm-3">
|
||||||
<input type="text" id="value" name="value" class="form-control" placeholder="IP ou ndd" >
|
<input type="text" id="rdata" name="rdata" class="form-control" placeholder="IP ou ndd" >
|
||||||
</div>
|
</div>
|
||||||
Votre adresse IP : <% user_ip %>
|
Votre adresse IP : <% user_ip %>
|
||||||
</div>
|
</div>
|
||||||
|
|
Reference in New Issue