3
0

readme++, daemon gère mieux IPv(4|6), script de déploiement++

This commit is contained in:
karchnu 2016-01-13 04:11:46 +01:00
parent d847d459a9
commit 3996187366
20 changed files with 521 additions and 69 deletions

View File

@ -29,7 +29,10 @@ our $wget = `which wget`; chomp $wget;
die "There is no wget on this computer." unless $wget;
sub get_ip {
for (split "\n", `$wget -nv -O - $checkip`) {
my $typeip = ($type =~ /AAAA/) ? '-6' : '-4';
my $cmd = "wget $typeip -nv -O - $checkip";
say "get IP : $cmd";
for (split "\n", `$cmd`) {
/^[0-9.]+$/ || /^[0-9a-f:]+$/ and return $_
}
undef

View File

@ -7,6 +7,9 @@ tld:
tmpdir: file:///media/fast/
# uncomment it if you want to only test the application views
#isviewtest: true
database:
sgbd: mysql # other options : see DBI module
name: dnsmanager

8
init/dependancies.ubuntu Normal file
View File

@ -0,0 +1,8 @@
cpanminus
libssl1.0.0
libssl-dev
make
gcc
libdbi-perl
libdbd-mysql-perl
mysql-server

View File

@ -1,13 +1,67 @@
#!/bin/bash
#!/bin/sh
# install applications
sudo apt-get install mysql-server # bind9
CDIR=`dirname $0`
# Get libs
bash ./get_libs.sh
usage() {
echo "usage : $0 cmd
cmd in :
# db install
mysql -u root --password="${PASS}" < init-create-user.sql
mysql -u root --password="${PASS}" < init-create-db.sql
mysql -u root --password="${PASS}" < init-grant-user.sql
mysql -u root --password="${PASS}" < init-tables.sql
installdep : install packages from your distribution
perlmodules : install cpan modules
dbinstall : install the database with a password provided by \$PATH
dbreinstall : reinstall the database with a password provided by \$PATH
all : do the full installation
" 2>&1
exit 1
}
if [ $# -lt 1 ] ; then
usage
fi
# install required applications
installdep_f() {
sudo apt-get update
cat ${CDIR}/dependancies.ubuntu | xargs sudo apt-get install
}
# install Perl modules
perlmodules_f() {
cpanm --local-lib=~/perl5 local::lib && eval $(perl -I ~/perl5/lib/perl5/ -Mlocal::lib)
cat ${CDIR}/perlmodules | xargs cpanm
}
# SQL
dbinstall_core_f() {
mysql -u root --password="${PASS}" < ${CDIR}/sql/init-create-user.sql
mysql -u root --password="${PASS}" < ${CDIR}/sql/init-create-db.sql
mysql -u root --password="${PASS}" < ${CDIR}/sql/init-grant-user.sql
mysql -u root --password="${PASS}" < ${CDIR}/sql/init-tables.sql
}
dbinstall_f() {
PASS=${PASS-notsodummy}
dbinstall_core_f
}
dbreinstall_f() {
PASS=${PASS-notsodummy}
mysql -u root --password="${PASS}" < ${CDIR}/sql/remove-db.sql
mysql -u root --password="${PASS}" < ${CDIR}/sql/remove-user.sql
dbinstall_core_f
}
case $1 in
installdep) installdep_f ;;
perlmodules) perlmodules_f ;;
dbinstall) dbinstall_f ;;
dbreinstall) dbreinstall_f ;;
all)
installdep_f
perlmodules_f
dbinstall_f
;;
*) usage ;;
esac

View File

@ -1,38 +0,0 @@
#!/bin/bash
## En attendant de faire de vrais paquets pour l'application
sudo apt-get update
sudo apt-get install libssl1.0.0 libssl-dev cpanminus make gcc \
libdbi-perl libdbd-mysql-perl
# sudo apt-get install bind9
cpanm --local-lib=~/perl5 local::lib && eval $(perl -I ~/perl5/lib/perl5/ -Mlocal::lib)
cpanm Dancer2
cpanm Dancer2::Plugin::Deferred
cpanm YAML::XS
cpanm Data::Dump
cpanm File::Basename
cpanm Find::Lib
cpanm Test::More
cpanm String::ShellQuote
cpanm Data::Structure::Util
cpanm Modern::Perl
cpanm Config::Simple
cpanm Crypt::Digest::SHA256
cpanm Dancer::Session::Storable
cpanm ExtUtils::MakeMaker
cpanm Storable
cpanm Plack::Handler::FCGI
cpanm Plack::Runner
cpanm DNS::ZoneParse
cpanm Net::OpenSSH
cpanm Template
cpanm Net::SSH
cpanm Date::Calc
cpanm Data::Validate::IP
# cpanm Template::Toolkit non trouvé

23
init/perlmodules Normal file
View File

@ -0,0 +1,23 @@
Dancer2
Dancer2::Plugin::Deferred
YAML::XS
Data::Dump
File::Basename
Find::Lib
Test::More
String::ShellQuote
Data::Structure::Util
Modern::Perl
Config::Simple
Crypt::Digest::SHA256
Dancer::Session::Storable
ExtUtils::MakeMaker
Storable
Plack::Handler::FCGI
Plack::Runner
DNS::ZoneParse
Net::OpenSSH
Template
Net::SSH
Date::Calc
Data::Validate::IP

View File

@ -1,10 +0,0 @@
#!/bin/bash
PASS="not-so-dummy"
mysql -u root --password=${PASS} < remove-db.sql
mysql -u root --password=${PASS} < remove-user.sql
mysql -u root --password=${PASS} < init-create-db.sql
mysql -u root --password=${PASS} < init-create-user.sql
mysql -u root --password=${PASS} < init-grant-user.sql
mysql -u root --password=${PASS} < init-tables.sql

View File

@ -15,12 +15,20 @@ use utf8;
use YAML::XS;
use configuration ':all';
use util ':all';
use rt::root ':all';
use rt::domain ':all';
use rt::user ':all';
use rt::admin ':all';
use rt::rootfake ':all';
use rt::domainfake ':all';
use rt::userfake ':all';
use rt::adminfake ':all';
use app;
our $isviewtest = is_view_test(get_cfg());
our $VERSION = '0.1';
sub what_is_next {
@ -79,6 +87,7 @@ sub get_session {
}
get '/' => sub {
return what_is_next rt_root_fake if $isviewtest;
what_is_next rt_root
get_session( qw/login passwd/ );
};
@ -86,6 +95,9 @@ get '/' => sub {
prefix '/domain' => sub {
post '/updateraw/:domain' => sub {
return what_is_next rt_dom_updateraw_fake
"" , "" , get_request( qw/address referer/ )
if $isviewtest;
what_is_next rt_dom_updateraw
get_session( qw/login passwd/ )
, get_param( qw/domain zoneupdated/)
@ -93,6 +105,9 @@ prefix '/domain' => sub {
};
post '/update/:domain' => sub {
return what_is_next rt_dom_add_entry_fake
"" , "", get_request( qw/referer/ )
if $isviewtest;
what_is_next rt_dom_add_entry
get_session( qw/login passwd/ )
, get_param( qw/domain type name ttl priority weight port rdata/ )
@ -100,6 +115,9 @@ prefix '/domain' => sub {
};
get '/details/:domain' => sub {
return what_is_next rt_dom_details_fake ""
, get_param( qw/expert/ )
, get_request( qw/address referer/ ) if $isviewtest;
what_is_next rt_dom_details
get_session( qw/login passwd/ )
, get_param( qw/domain expert/ )
@ -107,12 +125,16 @@ prefix '/domain' => sub {
};
post '/add/' => sub {
return what_is_next rt_dom_add_fake if $isviewtest;
what_is_next rt_dom_add
get_session( qw/login passwd/ )
, get_param( qw/domain tld/ );
};
get '/del/:domain' => sub {
return what_is_next rt_dom_del_fake
"" , "", get_request( qw/address referer/ )
if $isviewtest;
what_is_next rt_dom_del
get_session( qw/login passwd/ )
, get_param( qw/domain/ )
@ -120,6 +142,9 @@ prefix '/domain' => sub {
};
get '/del/:domain/:name/:ttl/:type/:priority/:rdata' => sub {
return what_is_next rt_dom_del_entry_fake
"" , "", get_request( qw/address referer/ )
if $isviewtest;
what_is_next rt_dom_del_entry
get_session( qw/login passwd/ )
, get_param( qw/domain name ttl type priority rdata/ )
@ -127,6 +152,9 @@ prefix '/domain' => sub {
};
get '/del/:domain/:name/:ttl/:type/:priority/:weight/:port/:rdata' => sub {
return what_is_next rt_dom_del_entry_fake
"" , "", get_request( qw/address referer/ )
if $isviewtest;
what_is_next rt_dom_del_entry
get_session( qw/login passwd/ )
, get_param( qw/domain name ttl type priority weight port rdata/ )
@ -134,6 +162,9 @@ prefix '/domain' => sub {
};
get '/del/:domain/:name/:ttl/:type/:rdata' => sub {
return what_is_next rt_dom_del_entry_fake
"" , "", get_request( qw/address referer/ )
if $isviewtest;
what_is_next rt_dom_del_entry
get_session( qw/login passwd/ )
, get_param( qw/domain name type ttl rdata/ )
@ -141,6 +172,9 @@ prefix '/domain' => sub {
};
post '/mod/:domain' => sub {
return what_is_next rt_dom_mod_entry_fake
"" , "", get_request( qw/address referer/ )
if $isviewtest;
what_is_next rt_dom_mod_entry
get_session( qw/login passwd/ )
, get_param( qw/domain type
@ -150,12 +184,14 @@ prefix '/domain' => sub {
};
get '/cliup/:login/:pass/:domain/:name/:type/:rdata' => sub {
return what_is_next rt_dom_cli_autoupdate_fake if $isviewtest;
what_is_next rt_dom_cli_autoupdate
get_session( qw// )
, get_param( qw/login pass domain name type rdata/ );
};
get '/cli/:login/:pass/:domain/:name/:type/:rdata/:ttl/:ip' => sub {
return what_is_next rt_dom_cli_mod_entry_fake if $isviewtest;
what_is_next rt_dom_cli_mod_entry
get_session( qw// )
, get_param( qw/login pass domain name type rdata ttl ip/ );
@ -163,6 +199,7 @@ prefix '/domain' => sub {
};
any ['get', 'post'] => '/admin' => sub {
return what_is_next rt_admin_fake if $isviewtest;
what_is_next rt_admin
get_session( qw/login passwd/ );
};
@ -170,6 +207,7 @@ any ['get', 'post'] => '/admin' => sub {
prefix '/user' => sub {
get '/home' => sub {
return what_is_next rt_user_home_fake if $isviewtest;
what_is_next rt_user_home
get_session( qw/login passwd/ )
, get_param( qw// )
@ -182,6 +220,9 @@ prefix '/user' => sub {
};
get '/del/:user' => sub {
return what_is_next rt_user_del_fake
"" , "", get_request( qw/address referer/ )
if $isviewtest;
what_is_next rt_user_del
get_session( qw/login passwd/ )
, get_param( qw/user/ )
@ -190,6 +231,7 @@ prefix '/user' => sub {
# add a user => registration
post '/add/' => sub {
return what_is_next rt_user_add_fake if $isviewtest;
what_is_next rt_user_add
get_session( qw// )
, get_param( qw/login password password2/ )
@ -197,17 +239,22 @@ prefix '/user' => sub {
};
get '/subscribe' => sub {
return what_is_next rt_user_subscribe_fake if $isviewtest;
what_is_next rt_user_subscribe
get_session( qw/login/ );
};
post '/changepasswd' => sub {
return what_is_next rt_user_changepasswd_fake if $isviewtest;
what_is_next rt_user_changepasswd
get_session( qw/login/ )
, get_param( qw/password/ );
};
get '/toggleadmin/:user' => sub {
return what_is_next rt_user_toggleadmin_fake
"" , "", get_request( qw/referer/ )
if $isviewtest;
what_is_next rt_user_toggleadmin
get_session( qw/login passwd/ )
, get_param( qw/user/ )
@ -215,6 +262,9 @@ prefix '/user' => sub {
};
post '/login' => sub {
return what_is_next rt_user_login_fake
"" , "", get_request( qw/referer/ )
if $isviewtest;
what_is_next rt_user_login
get_session( qw/login/ )
, get_param( qw/login password/ )

View File

@ -17,6 +17,7 @@ get_host_from_cfg
get_user_from_cfg
get_port_from_cfg
get_tmpdir_from_uri
is_view_test
/;
# bundle of exports (tags)
@ -32,6 +33,7 @@ get_host_from_cfg
get_user_from_cfg
get_port_from_cfg
get_tmpdir_from_uri
is_view_test
/] );
sub is_conf_file {
@ -121,6 +123,12 @@ sub get_zonedir_from_cfg {
URI->new($$cfg{zonedir})->path;
}
# in production by default, get the isviewtest value elsewise
sub is_view_test {
my $cfg = shift;
$$cfg{isviewtest}
}
sub get_host_from_cfg {
my $cfg = shift;

35
lib/rt/adminfake.pm Normal file
View File

@ -0,0 +1,35 @@
package rt::adminfake;
use configuration ':all';
use app;
use utf8;
use Data::Dump qw( dump );
use Exporter 'import';
# what we want to export eventually
our @EXPORT_OK = qw/rt_admin_fake/;
# bundle of exports (tags)
our %EXPORT_TAGS = ( all => [qw/rt_admin_fake/] );
sub rt_admin_fake {
my ($session, $param, $request) = @_;
my $res;
my $alldomains = [ { qw/domain toto.netlib.re login toto/ } ];
my $allusers = [ { qw/ login toto admin 0 / }
, { qw/login bidule admin 1/ }
, { qw/login machin admin 0 / } ];
my $domains = [ { qw/toto.netlib.re/ } ];
$$res{template} = 'administration';
$$res{params} = {
login => "toto"
, admin => 1
, domains => $domains
, alldomains => $alldomains
, allusers => $allusers
};
$res
}
1;

140
lib/rt/domainfake.pm Normal file
View File

@ -0,0 +1,140 @@
package rt::domainfake;
use v5.14;
use configuration ':all';
use encryption ':all';
use util ':all';
use app;
use utf8;
use Dancer ':syntax';
use Data::Dump qw( dump );
use Data::Validate::IP qw(is_ipv4 is_ipv6);
use MIME::Base64 qw(encode_base64 decode_base64);
use Exporter 'import';
# what we want to export eventually
our @EXPORT_OK = qw/
rt_dom_cli_mod_entry_fake
rt_dom_cli_autoupdate_fake
rt_dom_mod_entry_fake
rt_dom_del_entry_fake
rt_dom_del_fake
rt_dom_add_fake
rt_dom_details_fake
rt_dom_add_entry_fake
rt_dom_updateraw_fake
/;
# bundle of exports (tags)
our %EXPORT_TAGS = ( all => [qw/
rt_dom_cli_mod_entry_fake
rt_dom_cli_autoupdate_fake
rt_dom_mod_entry_fake
rt_dom_del_entry_fake
rt_dom_del_fake
rt_dom_add_fake
rt_dom_details_fake
rt_dom_add_entry_fake
rt_dom_updateraw_fake
/] );
sub rt_dom_cli_autoupdate_fake {
my ($session, $param, $request) = @_;
my $res;
$res
}
sub rt_dom_cli_mod_entry_fake {
my ($session, $param, $request) = @_;
my $res;
$res
}
sub rt_dom_mod_entry_fake {
my ($session, $param, $request) = @_;
my $res;
$$res{route} = '/domain/details/toto.netlib.re';
$res
}
sub rt_dom_del_entry_fake {
my ($session, $param, $request) = @_;
my $res;
$$res{route} = '/domain/details/toto.netlib.re';
$res
}
sub rt_dom_del_fake {
my ($session, $param, $request) = @_;
my $res;
$$res{route} = $$request{referer};
$res
}
sub rt_dom_add_fake {
my ($session, $param) = @_;
my $res;
$$res{route} = '/user/home';
$res
}
sub rt_dom_details_fake {
my ($session, $param, $request) = @_;
my $res;
$$res{template} = 'details';
$$res{params} = {
login => "toto"
, admin => 1
, domain => "toto.netlib.re."
, domain_zone => "
example.com. IN SOA ns.example.com. username.example.com. ( 2007120710 1d 2h 4w 1h )
example.com. 3600 IN NS ns
example.com. 3600 IN NS ns.somewhere.example.
example.com. 3600 IN MX 10 mail.example.com.
@ 3600 IN MX 20 mail2.example.com.
@ 3600 IN MX 50 mail3
example.com. 3600 IN A 192.0.2.1
example.com 3600 IN AAAA 3600 2001:db8:10::1
ns 3600 IN A 192.0.2.2
example.com 3600 IN AAAA 2001:db8:10::2
www 3600 IN CNAME example.com.
wwwtest 3600 IN CNAME www
mail 3600 IN A 192.0.2.3
mail2 3600 IN A 192.0.2.4
mail3 3600 IN A 192.0.2.5
"
, user_ip => $$request{address}
};
$$res{params}{zone} =[
{ qw/type A name bla ttl 30 rdata 10.0.0.1/ }
,{ qw/type AAAA name www ttl 36 rdata fe80::de4a:3eff:fe01:3b44/ }
,{ qw/type CNAME name web ttl 36 rdata www/ }
,{ qw/type MX name mail ttl 3600 priority 10 rdata web/ }
,{ qw/type SRV name _sip._tcp.example.com. ttl 86400 priority 0
weight 5 port 5060 rdata sipserver.example.com./ }
];
if($$param{expert}) {
$$res{params}{expert} = 1;
}
$res
}
sub rt_dom_add_entry_fake {
my ($session, $param, $request) = @_;
my $res;
$$res{route} = '/domain/details/toto.netlib.re';
$res
}
sub rt_dom_updateraw_fake {
my ($session, $param, $request) = @_;
my $res;
$$res{route} = '/domain/details/toto.netlib.re';
$res
}
1;

28
lib/rt/rootfake.pm Normal file
View File

@ -0,0 +1,28 @@
package rt::rootfake;
use configuration ':all';
use app;
use utf8;
use Exporter 'import';
# what we want to export eventually
our @EXPORT_OK = qw/rt_root_fake/;
# bundle of exports (tags)
our %EXPORT_TAGS = ( all => [qw/rt_root_fake/] );
sub rt_root_fake {
my ($session) = @_;
my $res;
$$res{template} = 'index';
$$res{params} = {
login => "toto"
, admin => 1
, domains => qw/toto.netlib.re/
};
$res
}
1;

90
lib/rt/userfake.pm Normal file
View File

@ -0,0 +1,90 @@
package rt::userfake;
use v5.14;
use configuration ':all';
use encryption ':all';
use app;
use utf8;
use YAML::XS;
use Exporter 'import';
# what we want to export eventually
our @EXPORT_OK = qw/
rt_user_login_fake
rt_user_del_fake
rt_user_toggleadmin_fake
rt_user_subscribe_fake
rt_user_changepasswd_fake
rt_user_add_fake
rt_user_home_fake
/;
# bundle of exports (tags)
our %EXPORT_TAGS = ( all => [qw/
rt_user_login_fake
rt_user_del_fake
rt_user_toggleadmin_fake
rt_user_subscribe_fake
rt_user_changepasswd_fake
rt_user_add_fake
rt_user_home_fake
/] );
sub rt_user_login_fake {
my ($session, $param, $request) = @_;
my $res;
$$res{route} = '/admin';
$res
}
sub rt_user_del_fake {
my ($session, $param, $request) = @_;
my $res;
$$res{route} = $$request{referer};
$res
}
sub rt_user_toggleadmin_fake {
my ($session, $param, $request) = @_;
my $res;
$$res{route} = $$request{referer};
$res
}
sub rt_user_subscribe_fake {
my ($session, $param, $request) = @_;
my $res;
$$res{route} = '/user/home';
$res
}
sub rt_user_changepasswd_fake {
my ($session, $param, $request) = @_;
my $res;
$$res{route} = '/user/home';
$res
}
sub rt_user_add_fake {
my ($session, $param, $request) = @_;
my $res;
$$res{route} = '/user/home';
$res
}
sub rt_user_home_fake {
my ($session, $param, $request) = @_;
my $res;
$$res{template} = 'home';
$$res{params} = {
login => "toto"
, admin => 1
, domains => [ {qw/domain toto.netlib.re/} ]
, provideddomains => [ qw/netlib.re. codelib.re./ ]
, domainName => ''
};
$res
}
1;

View File

@ -9,6 +9,45 @@ The association managing the infrastructure behind this service is [Alsace
Réseau Neutre][arn] which is an ethical ISP based in Alsace, France. Don't be
shy, go ask your questions !
## Tools
* [Dancer2](http://perldancer.org/)
* [Net::DNS](https://metacpan.org/pod/Net::DNS)
* [Bootstrap](http://twitter.github.io/bootstrap/)
* [DBD::mysql](https://metacpan.org/module/DBD::mysql)
* [Moo](https://metacpan.org/pod/Moo)
* [Crypt::Digest::SHA256](https://metacpan.org/pod/Crypt::Digest::SHA256)
## TODO
* zone delegation
* REST API
* captcha ?
# Installation (base)
I suggest using [perlbrew][perlbrew] and [cpanm][cpanm] for the installation,
to not change your current environment. So install them then :
perlbrew install perl-5.18.0
perlbrew switch perl-5.18.0
perlbrew exec sh init/deploiement.sh all
# Contribution (but only to the user interface)
If you want to contribute only on the application interface, you don't need to install and configure all the applications involved in the production release of dnsmanager.
First, uncomment "isviewtest" on **conf/config.yml** then :
perlbrew install perl-5.18.0
perlbrew switch perl-5.18.0
perlbrew exec sh init/deploiement.sh installdep
perlbrew exec sh init/deploiement.sh perlmodules
Finally, to run the application with fake views :
perlbrew exec plackup --port 3000 bin/app.psgi
# DNSmanager (fr)
Ce projet est un programme de gestion de zones DNS à partir d'un site web
@ -28,20 +67,39 @@ De manière factuelle :
- supprimer des zones, des utilisateurs
- vous aider sur IRC (#arn sur irc.geeknode.org) ! \o/
## Outils
# installation (base)
* [Dancer2](http://perldancer.org/)
* [Net::DNS](https://metacpan.org/pod/Net::DNS)
* [Bootstrap](http://twitter.github.io/bootstrap/)
* [DBD::mysql](https://metacpan.org/module/DBD::mysql)
* [Moo](https://metacpan.org/pod/Moo)
* [Crypt::Digest::SHA256](https://metacpan.org/pod/Crypt::Digest::SHA256)
L'installation de l'application se fait de préférence via
[perlbrew][perlbrew] et [cpanm][cpanm] ce qui permet d'installer les
bibliothèques sans toucher à votre installation de Perl. Installez ces
programmes puis faites :
## TODO
perlbrew install perl-5.18.0
perlbrew switch perl-5.18.0
perlbrew exec sh init/deploiement.sh all
* zone delegation
* REST API
# Contribuer (uniquement à l'interface)
Si vous souhaitez contribuer à *l'interface*, il suffit de décommenter la ligne
indiquant "isviewtest" dans le fichier de configuration **conf/config.yml**.
À partir de là, vous pouvez installer l'application comme ceci :
perlbrew install perl-5.18.0
perlbrew switch perl-5.18.0
perlbrew exec sh init/deploiement.sh installdep
perlbrew exec sh init/deploiement.sh perlmodules
Puis pour faire vos tests :
perlbrew exec plackup --port 3000 bin/app.psgi
## Ce qu'il reste à faire
* délégation de zone
* API REST
* captcha ?
[netlibre]: https://netlib.re/
[arn]: https://www.arn-fai.net
[perlbrew]: http://perlbrew.pl/
[cpanm]: http://search.cpan.org/~miyagawa/App-cpanminus-1.7040/bin/cpanm