Your IP : 18.226.133.136
Current Path : /opt/webdir/lib/ |
|
Current File : //opt/webdir/lib/bxSite.pm |
# manage site
# have to return
# document_root
# mysql: db, user, password
# memcached: host:port
# searchd: host:port
# cluster: ip_address|dns, ip_address|dns
# bx_kernel: 0(link), 1(own)
# bx_status: 0(disable), 1(enable)
# apache_config is usage for test bx_status
# dbconn is usage for getting mysql option
#
package bxSite;
use strict;
use warnings;
use Moose;
use File::Basename qw( dirname basename );
use File::Spec::Functions;
use Data::Dumper;
use DBI;
use Output;
use Pool;
use bxDaemon;
use bxMysql;
use Sys::Hostname;
use bxSiteFiles;
use File::Temp;
use bxInventory qw( generate_password generate_tmp );
# basic path for site
has 'site_name', is => 'ro', default => undef;
has 'site_dir', is => 'ro', default => undef;
has 'site_options', is => 'rw', lazy => 1, builder => 'get_site_options';
has 'dir_kernel', is => 'ro', default => 'bitrix';
has 'file_dbconn', is => 'ro', default => 'php_interface/dbconn.php';
has 'file_settings', is => 'ro', default => '.settings.php';
has 'apache', is => 'ro', default => '/etc/httpd/bx/conf';
has 'conf', is => 'ro', default => 'conf';
has 'pref', is => 'ro', default => 'bx_ext_';
has 'debug', is => 'ro', default => 0;
has 'logfile', is => 'ro', default => '/opt/webdir/logs/bxSiteNew.debug';
our $MYSOCKET = '/var/lib/mysqld/mysqld.sock';
# parse nginx config, found certificate options (process includes too)
sub https_options_in_config {
my ( $nginx_config, $ssl_info ) = @_;
#print "\ndebug: $nginx_config\n";
open( my $nh, '<', $nginx_config ) or return $ssl_info;
my @nginx_includes;
my $nginx_base = '/etc/nginx';
while (<$nh>) {
s/^\s+//;
s/\s+$//;
next if (/^$/);
next if (/^#/);
if (/^ssl_certificate\s+([^;]+);$/) {
my $ssl_cert = $1;
$ssl_cert =~ s/^['"]//;
$ssl_cert =~ s/['"]$//;
$ssl_info->{'HTTPSCert'} = $ssl_cert;
}
if (/^ssl_certificate_key\s+([^;]+);$/) {
my $ssl_priv = $1;
$ssl_priv =~ s/^['"]//;
$ssl_priv =~ s/['"]$//;
$ssl_info->{'HTTPSPriv'} = $ssl_priv;
}
if (/^ssl_trusted_certificate\s+([^;]+);$/) {
my $ssl_trusted_certificate = $1;
$ssl_trusted_certificate =~ s/^['"]//;
$ssl_trusted_certificate =~ s/['"]$//;
$ssl_info->{'HTTPSCertChain'} = $ssl_trusted_certificate;
}
if (/^ssl_protocols\s+/) {
$ssl_info->{'HTTPSConf'} = $nginx_config;
}
if ($ssl_info->{'HTTPSCert'} =~ m|^/home/bitrix/dehydrated|){
$ssl_info->{'HTTPSCertType'} = "letsencrypt";
} elsif ( $ssl_info->{'HTTPSCert'} =~ m|^/etc/nginx/certs| ){
$ssl_info->{'HTTPSCertType'} = "own";
}else {
$ssl_info->{'HTTPSCertType'} = "general";
}
if (/^include\s+([^;]+);$/) {
my $include_file = $1;
#print "include: $include_file\n";
$include_file =~ s/^['"]//;
$include_file =~ s/['"]$//;
if ( $include_file !~ m:^/: ) {
$include_file = catfile( $nginx_base, $include_file );
}
push @nginx_includes, $include_file;
}
}
close $nh;
my $include_size = @nginx_includes;
if (
(
not defined $ssl_info->{'HTTPSConf'}
or $ssl_info->{'HTTPSConf'} =~ /^$/
)
and $include_size > 0
)
{
foreach my $include_file (@nginx_includes) {
#print " include: $include_file\n";
$ssl_info = https_options_in_config( $include_file, $ssl_info );
if ( defined $ssl_info->{'HTTPSConf'}
&& $ssl_info->{'HTTPSConf'} !~ /^$/ )
{
next;
}
}
}
return $ssl_info;
}
# get nginx options for site from main config
sub get_nginx_options {
my $nginx_config = shift;
my $nginx_options = {
CompositeNginx => 'disable',
proxy_ignore_client_abort => 'off',
nginx_custom_settings => 'off',
nginx_bx_temp_files => 'off',
nginx_bx_temp_config => '',
nginx_custom_settings_directory => '',
};
if ( !-f $nginx_config ) { return $nginx_options; }
open( my $nh, '<', $nginx_config )
or return $nginx_options;
while (<$nh>) {
chomp;
s/^\s+//;
s/\s+$//;
next if (/^$/);
next if (/^#/);
if (/^set\s+\$use_composite_cache\s+\"\"\s*\;$/) {
$nginx_options->{'CompositeNginx'} = 'enable';
}
# proxy_ignore_client_abort on;
if (/^proxy_ignore_client_abort\s+on;$/) {
$nginx_options->{'proxy_ignore_client_abort'} = 'on';
}
# bx/site_settings/ksh770.office.bitrix.ru/
if (/^include\s+(bx\/site_settings\/[^\/]+)\/\*\.conf;$/) {
my $sub_dir = $1;
my $settings_dir = catfile('/etc/nginx/', $sub_dir);
if (-d $settings_dir){
$nginx_options->{'nginx_custom_settings'} = 'on';
$nginx_options->{'nginx_custom_settings_directory'} = $settings_dir;
}
if ( -f catfile( $settings_dir, 'bx_temp.conf' ) ){
$nginx_options->{nginx_bx_temp_files} = 'on';
$nginx_options->{nginx_bx_temp_config} = catfile( $settings_dir, 'bx_temp.conf' );
}
}
}
close $nh;
return $nginx_options;
}
# get map options for composite
# create option for site without composite
sub get_nginx_map_options {
my $site_name = shift;
my $nginx_options = {
CompositeNginxID => '',
CompositeNginxMap => '',
};
my $nginx_maps_dir = '/etc/nginx/bx/maps';
opendir( my $dh, $nginx_maps_dir )
or return $nginx_options;
my $new_id = 1;
# try found ID and map config
while ( my $f = readdir($dh) ) {
next if ( $f =~ /^\.\.?$/ );
next if ( -d catfile( $nginx_maps_dir, $f ) );
# if found map file with id
if ( $f =~ /^(\d+)\.cache_(\S+)\.conf$/ ) {
my $found_id = $1;
my $found_cn = sprintf "%d", $found_id;
my $found_site = $2;
# save id
if ( $found_cn > $new_id ) { $new_id = $found_cn; }
# test site name
if ( $found_site eq $site_name ) {
$nginx_options->{'CompositeNginxID'} = $found_id;
$nginx_options->{'CompositeNginxMap'} =
catfile( $nginx_maps_dir, $f );
}
}
}
closedir $dh;
# create ID if not exists
if ( $nginx_options->{'CompositeNginxID'} =~ /^$/ ) {
$nginx_options->{'CompositeNginxID'} = sprintf "%02d", $new_id + 1;
}
return $nginx_options;
}
# return DocumentRoot, ApacheConf, SiteName, PHP settings
sub apache_config_options {
my $self = shift;
my $site_name = $self->site_name;
my $apache_dir = $self->apache;
my $apache_ext = $self->conf;
my $apache_site_prefix = $self->pref;
my $message_p = ( caller(0) )[3];
my $message_t = __PACKAGE__;
my $logOutput = Output->new(
error => 0,
logfile => $self->logfile,
debug => $self->debug
);
my $apache_options = {
error => 0,
message => '',
ApacheConf => '',
ApacheConfScale => '',
ApacheConfNTLM => '',
DocumentRoot => '',
ServerName => '',
SiteCharset => 'utf-8',
phpUploadDir => '',
phpSessionDir => '',
phpMsmtpAccount => 'default',
};
# external kernel variant
if ( not defined $site_name ) {
$apache_options->{error} = 1;
return $apache_options;
}
$logOutput->log_data("$message_p: parse options for $site_name");
my $apache_conf = catfile( $apache_dir, $site_name . '.' . $apache_ext );
my $apache_conf_scale = catfile(
"/etc/httpd/bx-scale/conf",
$site_name . '.' . $apache_ext
);
my $apache_conf_ntlm = catfile(
$apache_dir, 'ntlm_'. $site_name . '.' . $apache_ext
);
if ($site_name eq 'default'){
$apache_conf_ntlm = catfile(
$apache_dir, 'ntlm_'. hostname . '.' . $apache_ext
);
}
if ( -f $apache_conf_ntlm ){
$apache_options->{ApacheConfNTLM} = $apache_conf_ntlm;
}
if ( $site_name !~ /^default$/ ) {
$apache_conf = catfile( $apache_dir,
$apache_site_prefix . $site_name . '.' . $apache_ext );
$apache_conf_scale = catfile(
"/etc/httpd/bx-scale/conf",
'ext_' . $site_name . '.' . $apache_ext
);
}
$apache_options->{ApacheConfScale} = $apache_conf_scale;
if ( !-f $apache_conf ) {
$apache_options->{'error'} = 1;
$apache_options->{'message'} =
"$message_p: Not found $apache_conf for $site_name";
}
else {
$apache_options->{'ApacheConf'} = $apache_conf;
# get options from file
open( my $ah, '<', $apache_conf )
or die "Cannot open $apache_conf: $!";
while ( my $line = <$ah> ) {
next if ( $line =~ /^$/ );
next if ( $line =~ /^#/ );
$line =~ s/^\s+//;
$line =~ s/\s+$//;
if ( $line =~ /^ServerName\s+(\S+)$/ ) {
$apache_options->{'ServerName'} = $1;
}
if ( $line =~ /^DocumentRoot\s+(\S+)$/ ) {
$apache_options->{'DocumentRoot'} = $1;
}
if ( $line =~ /^php_admin_value\s+session.save_path\s+(\S+)$/ ) {
$apache_options->{'phpSessionDir'} = $1;
}
if ( $line =~ /^php_admin_value\s+upload_tmp_dir\s+(\S+)$/ ) {
$apache_options->{'phpUploadDir'} = $1;
}
if ( $line =~
/^php_admin_value\s+mbstring.internal_encoding\s+(\S+)$/ )
{
$apache_options->{'SiteCharset'} = 'windows-1251';
}
if ( $line =~
/^php_admin_value\s+sendmail_path\s+['"]msmtp([^'"]+)['"]$/ )
{
my $options = $1;
if ( $options =~ /-a\s+(\S+)/ ) {
$apache_options->{'phpMsmtpAccount'} = $1;
}
}
# alias id addional values, now we not use them, but who knows
if ( $line =~ /^ServerAlias\s+(.+)$/ ) {
my @server_aliases = split( /\s+/, $1 );
my $sa_count = 0;
foreach my $sa (@server_aliases) {
$sa_count++;
$apache_options->{ 'ServerAlias'
. sprintf( "%02d", $sa_count ) } = $sa;
}
$apache_options->{'ServerAliasesCount'} = $sa_count;
}
}
close $ah;
# ServerName is not defined in config file => use hostname
if ( not defined $apache_options->{'ServerName'}
or $apache_options->{'ServerName'} =~ /^$/ )
{
$apache_options->{'ServerName'} = hostname;
}
# default values for phpSessionDir and phpUploadDir
if ( not defined $apache_options->{'phpSessionDir'} ) {
$apache_options->{'phpSessionDir'} =
( $site_name =~ /^default$/ )
? "/tmp/php_sessions/www"
: "/tmp/php_sessions/ext_www/$site_name";
}
if ( not defined $apache_options->{'phpUploadDir'} ) {
$apache_options->{'phpSessionDir'} =
( $site_name =~ /^default$/ )
? "/tmp/php_upload/www"
: "/tmp/php_upload/ext_www/$site_name";
}
}
$logOutput->log_data( "$message_p: " . Dumper($apache_options) );
return $apache_options;
}
# return
# 0 - disabled
# 1 - enabled
sub getWebClusterStatus {
my ($self) = @_;
my $message_p = ( caller(0) )[3];
my $message_t = 'bxSite';
my $group_vars = "/etc/ansible/group_vars/bitrix-web.yml";
if ( ! -f $group_vars ){
return 0;
}
my $status = '';
open(my $hv, "<", $group_vars)
or return 0;
while(<$hv>){
chomp;
s/^\s+//;
s/\s+$//;
next if (/^#/);
next if (/^$/);
if (/^cluster_web_configure:\s*(\S+)/){
$status = $1;
}
}
close $hv;
if ($status eq "enable"){
return 1;
}
return 0;
}
sub nginx_config_options {
my $self = shift;
my $message_p = ( caller(0) )[3];
my $message_t = __PACKAGE__;
my $logOutput = Output->new(
error => 0,
logfile => $self->logfile,
debug => $self->debug
);
my $site_name = $self->site_name;
my $nginx_options = {
error => 0,
message => '',
NginxHTTPConfig => '',
NginxHTTPSConfig => '',
NginxHTTPDir => '', # site_avaliable
NginxHTTPEDir => '', # site_enabled
NginxType => '',
NginxPort => '',
SiteShort => '',
SiteCsync2 => '',
HTTPSCert => '',
HTTPSPriv => '',
HTTPSConf => '',
HTTPSCertChain => '',
HTTPSCertType => '',
CompositeNginx => '',
CompositeNginxID => '',
CompositeNginxMap => '',
};
$logOutput->log_data("$message_p: estimate nginx options for $site_name");
my $site_fancy = ( $site_name !~ /^default$/ ) ? $site_name : "s1";
my $conf_https_nginx =
( $site_name =~ /^default$/ )
? "ssl." . $site_fancy
: "bx_ext_ssl_" . $site_fancy;
my $conf_http_nginx =
( $site_name =~ /^default$/ ) ? $site_fancy : "bx_ext_" . $site_fancy;
# change https config for cluster case
my $is_cluster_enabled = getWebClusterStatus();
if ($is_cluster_enabled){
$conf_https_nginx = "https_balancer_" . $site_name;
}
$conf_http_nginx .= '.conf';
$conf_https_nginx .= '.conf';
#print $site_name, "\n";
$nginx_options->{'SiteShort'} = $site_name;
$nginx_options->{'SiteShort'} =~ s/^([^\.]+)\..+$/$1/;
$nginx_options->{'SiteCsync2'} = $site_name;
$nginx_options->{'SiteCsync2'} =~ s/[\-\_\.]//g;
$nginx_options->{'SiteCsync2'} =~ s/^[\d]+//;
$nginx_options->{'NginxHTTPConfig'} = $conf_http_nginx;
$nginx_options->{'NginxHTTPSConfig'} = $conf_https_nginx;
# cluster or single installations
my @enable_nginx_dirs =
( '/etc/nginx/bx/site_enabled', '/etc/nginx/bx/site_ext_enabled' );
my @cluster_nginx_dir = '/etc/nginx/bx/site_cluster';
# search nginx config file in enable dirs
foreach my $dir (@enable_nginx_dirs) {
$logOutput->log_data(
"$message_p: process $dir, search $conf_http_nginx");
my $conf_http_nginx_fn = catfile( $dir, $conf_http_nginx );
# test if file exists
if ( -f $conf_http_nginx_fn ) {
$logOutput->log_data("$message_p: found $conf_http_nginx_fn");
$nginx_options->{'NginxHTTPDir'} = $dir;
# get source file
if ( -l $conf_http_nginx_fn ) {
my $conf_http_nginx_link = readlink($conf_http_nginx_fn);
$logOutput->log_data(
"$message_p: $conf_http_nginx_fn is link to $conf_http_nginx_link"
);
$nginx_options->{'NginxHTTPDir'} =
dirname($conf_http_nginx_link);
$nginx_options->{'NginxHTTPEDir'} = $dir;
$logOutput->log_data( "$message_p: set NginxHTTPDir to "
. $nginx_options->{'NginxHTTPDir'} );
# test if cluster install exists
if ( $nginx_options->{'NginxHTTPDir'} =~ m|/site_cluster$| ) {
$logOutput->log_data("$message_p: found cluster config");
$nginx_options->{'NginxType'} = 'cluster';
$nginx_options->{'NginxPort'} = 8080;
}
else {
$logOutput->log_data(
"$message_p: not found cluster config, set default options for site"
);
$nginx_options->{'NginxType'} = 'single';
$nginx_options->{'NginxPort'} = 80;
}
}
else {
$logOutput->log_data(
"$message_p: found ordinary file for site config");
$nginx_options->{'NginxType'} = 'single';
$nginx_options->{'NginxPort'} = 80;
}
}
}
# test options and return error is something not found
if ( not defined $nginx_options->{'NginxHTTPDir'} ) {
$nginx_options->{'error'} = 2;
$nginx_options->{'message'} =
"$message_p: not found nginx config file for $site_name";
}
#$logOutput->log_data("$message_p: ".Dumper($nginx_options));
# get cerificate options
if ( $nginx_options->{'NginxType'} =~ /^cluster$/ ) {
my $nginx_https_fn = catfile('/etc/nginx/bx/site_enabled', $conf_https_nginx);
$nginx_options =
https_options_in_config( $nginx_https_fn, $nginx_options );
if (-l $nginx_https_fn ){
$nginx_options->{'NginxHTTPSFullPath'} = readlink $nginx_https_fn;
} else {
$nginx_options->{'NginxHTTPSFullPath'} = $nginx_https_fn;
}
}
else {
my $nginx_https_fn = catfile(
$nginx_options->{'NginxHTTPDir'},
$nginx_options->{'NginxHTTPSConfig'}
);
if (-l $nginx_https_fn ){
$nginx_options->{'NginxHTTPSFullPath'} = readlink $nginx_https_fn;
} else {
$nginx_options->{'NginxHTTPSFullPath'} = $nginx_https_fn;
}
$nginx_options =
https_options_in_config( $nginx_https_fn, $nginx_options );
}
# get options from primary nginx config
# CompositeNginx - enable or not
my $get_nginx_options = get_nginx_options(
catfile(
$nginx_options->{'NginxHTTPDir'},
$nginx_options->{'NginxHTTPConfig'}
)
);
foreach ( keys %$get_nginx_options ) {
$nginx_options->{$_} = $get_nginx_options->{$_};
}
# Search site personal setting (map file) and id internal variable
my $get_nginx_map_options = get_nginx_map_options($site_name);
foreach ( keys %$get_nginx_map_options ) {
$nginx_options->{$_} = $get_nginx_map_options->{$_};
}
return $nginx_options;
}
sub bx_https_options {
my ( $self, $site_root ) = @_;
my $message_p = ( caller(0) )[3];
my $message_t = __PACKAGE__;
my $site_name = $self->site_name;
my $logOutput = Output->new(
error => 0,
logfile => $self->logfile,
debug => $self->debug
);
$logOutput->log_data(
"$message_p: try defined https options for site $site_name");
my $ssl_info = { HTTPS => 'disable', };
my $site_ssl_switcher = catfile( $site_root, '.htsecure' );
if ( -f $site_ssl_switcher ) {
$ssl_info->{'HTTPS'} = 'enable';
}
return $ssl_info;
}
sub bx_email_options {
my ( $self, $msmtprc_account ) = @_;
my $message_p = ( caller(0) )[3];
my $message_t = __PACKAGE__;
my $site_name = $self->site_name;
my $logOutput = Output->new(
error => 0,
logfile => $self->logfile,
debug => $self->debug
);
$logOutput->log_data(
"$message_p: try defined email options for site $site_name");
my $msmtp_info = {
EmailAddress => undef,
EmailAccount => undef,
SMTPHost => undef,
SMTPPort => undef,
SMTPTLS => "off",
SMTPUser => undef,
SMTPPassword => undef,
};
my $msmtp_conf = "/home/bitrix/.msmtprc";
my $bxenv_conf = "/etc/php.d/bitrixenv.ini";
if ( !-f $msmtp_conf ) {
return $msmtp_info;
}
open( my $mh, '<', $msmtp_conf )
or return $msmtp_info;
my $account = '';
while ( my $line = <$mh> ) {
$line =~ s/^\s+//;
$line =~ s/\s+$//;
next if ( $line =~ /^#/ );
next if ( $line =~ /^$/ );
if ( $line =~ /^account\s+(\S+)$/ ) {
$account = $1;
}
if ( $account =~ /^$msmtprc_account$/ ) {
$msmtp_info->{'EmailAccount'} = $account;
if ( $line =~ /^from\s+(\S+)$/ ) {
$msmtp_info->{'EmailAddress'} = $1;
}
if ( $line =~ /^host\s+(\S+)$/ ) {
$msmtp_info->{'SMTPHost'} = $1;
}
if ( $line =~ /^port\s+(\S+)$/ ) {
$msmtp_info->{'SMTPPort'} = $1;
}
if ( $line =~ /^user\s+(\S+)$/ ) {
$msmtp_info->{'SMTPUser'} = $1;
}
if ( $line =~ /^password\s+(\S+)$/ ) {
$msmtp_info->{'SMTPPassword'} = $1;
}
if ( $line =~ /^password\s*$/ ){
$msmtp_info->{'SMTPPassword'} = "";
}
if ( $line =~ /^tls\s+(\S+)$/ ) {
$msmtp_info->{'SMTPTLS'} = $1;
}
}
}
close $mh;
return $msmtp_info;
}
sub get_site_options {
my $self = shift;
my $message_p = ( caller(0) )[3];
my $message_t = __PACKAGE__;
my $site_name = $self->site_name;
my $site_dir = $self->site_dir;
my $logOutput = Output->new(
error => 0,
logfile => $self->logfile,
debug => $self->debug,
);
my $site_options = {
"error" => 0,
"message" => '',
"SiteName" => $site_name,
"ApacheConf" => '',
"BackupCronFile" => '',
"BackupDay" => '',
"BackupFolder" => '',
"BackupHour" => '',
"BackupMinute" => '',
"BackupMonth" => '',
"BackupTask" => '',
"BackupVersion" => '',
"BackupWeekDay" => '',
"CronFile" => '',
"CronTask" => '',
"DBHost" => '',
"DBLogin" => '',
"DBName" => '',
"DBPassword" => '',
"DBType" => '',
"DBConn" => '',
"DocumentRoot" => '',
"EmailAccount" => undef,
"EmailAddress" => undef,
"HTTPS" => '',
"HTTPSCert" => '',
"HTTPSConf" => '',
"HTTPSPriv" => '',
'HTTPSCertChain' => '',
'HTTPSCertType' => '',
"NginxHTTPConfig" => '',
"NginxHTTPDir" => '',
"NginxHTTPSConfig" => '',
"NginxPort" => '',
"NginxType" => '',
"SMTPHost" => undef,
"SMTPPassword" => undef,
"SMTPPort" => undef,
"SMTPTLS" => 'off',
"SMTPUser" => undef,
"ServerName" => '',
"SiteCharset" => '',
"SiteInstall" => '',
"SiteShort" => '',
"SiteCsync2" => '',
"SiteStatus" => '',
"SphinxConnection" => '',
"SphinxIndexName" => '',
"phpSessionDir" => '',
"phpUploadDir" => '',
"phpMsmtpAccount" => '',
"ModuleCluster" => '',
"ModuleScale" => '',
"NTLM_use_ntlm" => 'N',
"NTLM_bitrixvm_auth_support" => 'N',
"SiteKernelDir" => '',
"SiteKernelDB" => '',
CompositeStatus => 'disable',
CompositeStorage => '',
CompositeDomains => [],
CompositeExcludeUri => [],
CompositeIncludeUri => [],
CompositeExcludeParams => [],
CompositeMemcachedHost => '',
CompositeMemcachedPort => '',
CompositeNginx => 'disable',
};
### apache options for site
my $apache_options = $self->apache_config_options();
foreach my $apache_k ( keys %$apache_options ) {
$site_options->{$apache_k} = $apache_options->{$apache_k};
}
# if error return found information with error
if ( $apache_options->{'error'} ) {
# external kernel doesn't contain web configs
if ( not defined $site_dir ) {
$site_options->{'SiteStatus'} = 'error';
return $site_options;
}
else {
my $bxSiteFiles = bxSiteFiles->new(
site_dir => $site_dir,
site_conf => 'not_found'
);
my $bxSiteFilesOptions = $bxSiteFiles->site_files_options;
$bxSiteFilesOptions->{'SiteName'} = "ext_" . basename($site_dir);
$bxSiteFilesOptions->{'SiteShort'} =
$bxSiteFilesOptions->{'SiteName'};
$bxSiteFilesOptions->{'SiteCsync2'} =
$bxSiteFilesOptions->{'SiteName'};
foreach my $fo ( keys %$bxSiteFilesOptions ) {
$site_options->{$fo} = $bxSiteFilesOptions->{$fo};
}
return $site_options;
}
}
### nginx options for site
my $nginx_options = $self->nginx_config_options();
foreach my $nginx_k ( keys %$nginx_options ) {
$site_options->{$nginx_k} = $nginx_options->{$nginx_k};
}
# if error return found information with error
if ( $nginx_options->{'error'} ) {
$site_options->{'SiteStatus'} = 'error';
return $site_options;
}
#print Dumper($nginx_options);
### folder and config options
my $bxSiteFiles = bxSiteFiles->new(
site_dir => $site_options->{'DocumentRoot'},
site_conf => 'found'
);
my $bxSiteFilesOptions = $bxSiteFiles->site_files_options;
foreach my $fo ( keys %$bxSiteFilesOptions ) {
$site_options->{$fo} = $bxSiteFilesOptions->{$fo};
}
if ( $bxSiteFilesOptions->{'error'} ) {
return $site_options;
}
#print "SiteFiles: ",Dumper($bxSiteFilesOptions);
### email options
if ( $site_options->{'phpMsmtpAccount'} !~ /^$/ ) {
my $bx_email_options =
$self->bx_email_options( $site_options->{'phpMsmtpAccount'}, );
foreach my $email_k ( keys %$bx_email_options ) {
$site_options->{$email_k} = $bx_email_options->{$email_k};
}
}
### cron settings
if ( $site_options->{'SiteInstall'} !~ /^ext_kernel$/ ) {
### https settings on site
my $bx_https_options = $self->bx_https_options(
$site_options->{'DocumentRoot'},
$site_options->{'NginxType'},
);
foreach my $ssl_k ( keys %$bx_https_options ) {
$site_options->{$ssl_k} = $bx_https_options->{$ssl_k};
}
}
return $site_options;
}
# generate my.cnf file with connection options for the site or password file for ansible lookups
sub my_connect {
my ( $self, $type, $tmpdir ) = @_;
$type = "password_file" if ( not defined $type );
my $site_name = $self->site_name;
my $site_dir = $self->site_dir;
if ( ( not defined $site_name ) && ( not defined $site_dir ) ) {
return Output->new(
error => 1,
message =>
"For site status you must defined site_name or document root",
);
}
if ( $type !~ /^(password_file|my_cnf)$/ ) {
return Output->new(
error => 1,
message =>
"Unknown type=$type; Supported types: password_file and my_cnf",
);
}
my $so = $self->site_options;
if ( not defined $site_name ) {
$site_name = "ext_" . basename($site_dir);
}
# generate tmp file
my $tmp_file = generate_tmp( $type, $tmpdir );
open( my $h, '>', $tmp_file )
or return Output->new(
error => 1,
message => "Cannot open temporary file=$tmp_file"
);
if ( $type eq "password_file" ) {
print $h $so->{DBPassword};
$so->{DBPasswordFile} = $tmp_file;
}
elsif ( $type eq "my_cnf" ) {
# generate my.cnf file
print $h "# bitrix management console config file\n";
print $h "# site=" . $so->{SiteName} . "\n";
print $h "[client]\n";
if ( $so->{DBHost} =~ /^(localhost|127\.0\.0\.1)$/ ) {
print $h "socket=$MYSOCKET\n";
}
else {
print $h "host=" . $so->{DBHost} . "\n";
}
print $h "user=" . $so->{DBLogin} . "\n";
# my.cnf parsing allows quoting only \, ' or "
# we need quoted ' char only
my $my_escaped_password = $so->{DBPassword};
if ( $my_escaped_password =~ /'/ ) {
$my_escaped_password =~ s/'/\\'/;
}
print $h "password='$my_escaped_password'\n";
$so->{DBMyCnf} = $tmp_file;
}
close $h;
my $message_t = __PACKAGE__;
return Output->new(
error => 0,
data => [ $message_t, { $site_name => $so } ],
);
}
sub statusSite {
my $self = shift;
my $site_name = $self->site_name;
my $site_dir = $self->site_dir;
if ( ( not defined $site_name ) && ( not defined $site_dir ) ) {
return Output->new(
error => 1,
message =>
"For site status you must defined site_name or document root",
);
}
my $site_options = $self->site_options;
if ( not defined $site_name ) {
$site_name = "ext_" . basename($site_dir);
}
my $message_t = __PACKAGE__;
return Output->new(
error => 0,
data => [ $message_t, { $site_name => $site_options } ],
);
}
sub statusUpdateSite {
my $self = shift;
my $site_name = $self->site_name;
my $site_dir = $self->site_dir;
if ( not defined $site_name ) { $site_name = "ext_" . basename($site_dir); }
my $site_options = $self->get_site_options;
my $message_t = __PACKAGE__;
return Output->new(
error => 0,
data => [ $message_t, { $site_name => $site_options } ],
);
}
# add or update php values in apache config file
sub replace2apache {
my ( $self, $site_values ) = @_;
#print $site_conf," =>",Dumper($site_values);
my $message_p = ( caller(0) )[3];
my $message_t = __PACKAGE__;
my $logOutput = Output->new(
error => 0,
logfile => $self->logfile,
debug => $self->debug
);
my $site_status = $self->site_options->{'SiteStatus'};
my $site_name = $self->site_name;
if ( $site_status =~ /^error$/ ) {
my $site_error = $self->site_options->{'error'};
if ( $site_error != 5 ) {
return Output->new(
error => 1,
message => "Site $site_name status=$site_status"
. " not allow manage apache settings for it",
);
}
}
my $apache_conf = $self->site_options->{'ApacheConf'};
my $apache_temp = $apache_conf . '.temp';
$logOutput->log_data("$message_p: start update $apache_conf: $!");
# create work hash with values and statuses
my ( %php_values, %php_deleted, $php_deleted, $php_values );
$php_values = $php_deleted = 0;
foreach my $key ( sort keys %$site_values ) {
if ( defined $site_values->{$key} ) {
$php_values{$key} = [ $site_values->{$key}, 0 ];
$php_values++;
}
else {
$php_deleted{$key} = 0;
$php_deleted++;
}
}
my $site_root = "";
my $proc_dir = undef;
open( my $sc, '<', $apache_conf )
or return Output->new(
error => 1,
message => "$message_p: Cannot open $apache_conf: $!",
);
open( my $st, '>', $apache_temp )
or return Output->new(
error => 1,
message => "$message_p: Cannot open $apache_temp: $!",
);
# create new values in tmp file
while (<$sc>) {
s/\s+$//;
my $line = $_;
if ( $line =~ /^\s*DocumentRoot\s+(\S+)$/ ) {
$site_root = $1;
#print "DocumentRoot: $site_root\n";
}
if ( $line =~ /^\s*\<Directory\s+([^\>]+)\>$/ ) {
$proc_dir = $1;
#print "Process directory: $proc_dir\n";
}
# update existen options
if ( defined $proc_dir && $proc_dir =~ /^$site_root$/ ) {
# found php value
if ( $line =~ /^\s*php_admin_value\s+(\S+)\s+(.+)$/ ) {
my $php_key = $1;
my $php_val = $2;
#print " Found key=$php_key val=$php_val\n";
if ( grep /^$php_key$/, keys %php_values ) {
$logOutput->log_data(
"$message_p: update $php_key from $php_val to "
. $php_values{$php_key}->[0] );
#print " Replace key=$php_key\n";
$line =~
s/$php_key\s+(.+)$/$php_key "$php_values{$php_key}->[0]"/;
$php_values{$php_key}->[1] = 1;
}
if ( grep /^$php_key$/, keys %php_deleted ) {
$logOutput->log_data(
"$message_p: delete $php_key in the apache config "
. $apache_conf );
$line =~ s/$php_key\s+(.+)$/#$php_key $1/;
$php_deleted{$php_key} = 1;
}
}
# close directory part and add options that not in the file
if ( $line =~ /^\s*\<\/Directory\>$/ ) {
if ( $proc_dir =~ /^$site_root$/ ) {
#print "Finish processing: $proc_dir\n\n";
foreach my $php_key ( keys %php_values ) {
#print "$php_key: ",$php_values{$php_key}->[1],"\n";
if ( $php_values{$php_key}->[1] == 0 ) {
$logOutput->log_data(
"$message_p: create $php_key set it to "
. $php_values{$php_key}->[0] );
print $st
qq( php_admin_value $php_key "$php_values{$php_key}->[0]"\n);
$php_values{$php_key}->[1] = 1;
}
}
}
$proc_dir = undef;
}
}
print $st $line, "\n";
}
close $sc;
close $st;
# create backup config
$logOutput->log_data(
"$message_t: create backup for $apache_conf and replace it by new values"
);
rename $apache_conf, $apache_conf . ".bak";
rename $apache_temp, $apache_conf;
# restart httpd
my $po = Pool->new();
my $ansData = $po->ansible_conf;
my $cmd_play = $ansData->{'playbook'};
my $cmd_conf = catfile( $ansData->{'base'}, "web.yml" );
my $cmd_opts = { 'manage_web' => 'restart_web' };
my $dh = bxDaemon->new(
debug => $self->debug,
task_cmd => qq($cmd_play $cmd_conf)
);
my $created_process =
$dh->startAnsibleProcess( 'restart_web_services', $cmd_opts );
return Output->new(
error => 0,
data => [ $message_p, $apache_conf ]
);
}
# disable email account in config file
sub del2msmtp {
my $site_name = shift;
my $msmtp_conf = shift;
my $message_p = ( caller(0) )[3];
my $message_t = __PACKAGE__;
my $msmtp_temp = $msmtp_conf . ".temp";
open( my $mc, $msmtp_conf )
or return Output->new(
error => 1,
message => "$message_p: Cannot open $msmtp_temp: $!",
);
open( my $mt, ">" . $msmtp_temp )
or return Output->new(
error => 1,
message => "$message_p: Cannot open $msmtp_temp: $!",
);
# comment data for site_name
my $account = "";
while (<$mc>) {
s/^\s+//;
s/\s+$//;
next if (/^$/);
my $line = $_;
# account alice
if (/^account\s+(\S+)$/) {
$account = $1;
}
if ( $account =~ /^$site_name$/ ) {
$line = "#" . $line;
}
print $mt $line, "\n";
}
close $mt;
close $mc;
# delete file with old data
unlink $msmtp_conf;
rename $msmtp_temp, $msmtp_conf;
# change access rights
chmod 0600, $msmtp_conf;
my $uid = getpwnam 'bitrix';
my $gid = getgrnam 'bitrix';
chown $uid, $gid, $msmtp_conf;
return Output->new(
error => 0,
data => [ $message_p, $msmtp_conf ]
);
}
# create account data for site
sub add2msmtp {
my $site_name = shift;
my $site_email_settings = shift;
my $msmtp_conf = shift;
my $message_p = ( caller(0) )[3];
my $message_t = __PACKAGE__;
open( my $mh, ">>" . $msmtp_conf )
or return Output->new(
error => 1,
message => "$message_p: Cannot open $msmtp_conf: $!",
);
if (not defined $site_email_settings->{'SMTPPassword'}){
if (defined $site_email_settings->{'SMTPPasswordFile'}){
open(my $fh, '<', $site_email_settings->{'SMTPPasswordFile'})
or return Output->new(
error => 1,
message => "$message_p: Cannot open ". $site_email_settings->{'SMTPPasswordFile'},
);
$site_email_settings->{'SMTPPassword'} = <$fh>;
close $fh;
unlink $site_email_settings->{'SMTPPasswordFile'};
}
}
# basic settings
my $msmtp_info = qq(
\# smtp account configuration for $site_name
account $site_name
logfile /home/bitrix/msmtp_$site_name.log
host $site_email_settings->{'SMTPHost'}
port $site_email_settings->{'SMTPPort'}
from $site_email_settings->{'EmailAddress'}
aliases /etc/aliases
keepbcc off);
# auth settings
if ( defined $site_email_settings->{'SMTPUser'} ) {
my $smtp_auth = 'on';
if ( ( defined $site_email_settings->{'SMTPAuth'} )
&& ( $site_email_settings->{'SMTPAuth'} !~ /^(auto|on)$/ ) )
{
$smtp_auth = $site_email_settings->{'SMTPAuth'};
}
my $pass = ($site_email_settings->{'SMTPPassword'})?
$site_email_settings->{'SMTPPassword'}:
"";
$msmtp_info = $msmtp_info . qq(
auth $smtp_auth
user $site_email_settings->{'SMTPUser'}
password $pass);
}
else {
$msmtp_info = $msmtp_info . qq(
auth off);
}
# tls settings
if ( defined $site_email_settings->{'SMTPTLS'}
&& $site_email_settings->{'SMTPTLS'} =~ /^(on|yes)$/i )
{
$msmtp_info = $msmtp_info . qq(
tls on
tls_certcheck off);
if ( $site_email_settings->{'EmailAddress'} =~ /yandex\.ru/ ) {
$msmtp_info = $msmtp_info . qq(
tls_starttls on
);
}
}
# save info and change access rights
print $mh $msmtp_info, "\n";
close $mh;
chmod 0600, $msmtp_conf;
my $uid = getpwnam 'bitrix';
my $gid = getgrnam 'bitrix';
chown $uid, $gid, $msmtp_conf;
return Output->new(
error => 0,
data => [ $message_p, $msmtp_conf ]
);
}
# delete email options for site
sub deleteEmailForSite {
my ($self) = @_;
my $site_name = $self->site_name;
my $message_p = ( caller(0) )[3];
my $message_t = __PACKAGE__;
my $logOutput = Output->new(
error => 0,
logfile => $self->logfile,
debug => $self->debug
);
$logOutput->log_data("$message_p: delete email settings for $site_name");
# update personal apache config fo site
my $apache_conf = $self->site_options->{'ApacheConf'};
my %msmtp_options = ( 'sendmail_path' => undef );
my $update_apache = $self->replace2apache( \%msmtp_options );
if ( $update_apache->is_error ) { return $update_apache; }
# delete site info in msmtp config
my $msmtp_conf = "/home/bitrix/.msmtprc";
my $msmtp_update = undef;
# if file exists => delete old site's data
if ( -f $msmtp_conf ) {
$msmtp_update = del2msmtp( $site_name, $msmtp_conf );
if ( $msmtp_update->is_error ) { return $msmtp_update }
}
return $self->statusUpdateSite();
}
# update or create email settings
sub createEmailForSite {
my $self = shift;
my $site_email_settings = shift;
my $site_name = $self->site_name;
my $message_p = ( caller(0) )[3];
my $message_t = __PACKAGE__;
my $logOutput = Output->new(
error => 0,
logfile => $self->logfile,
debug => $self->debug
);
$logOutput->log_data("$message_p: update email settings for $site_name");
my $site_status = $self->site_options->{'SiteStatus'};
if ( $site_status =~ /^error$/ ) {
my $site_error = $self->site_options->{'error'};
if ( $site_error != 5 ) {
return Output->new(
error => 1,
message =>
"Site $site_name status=$site_status, not allow create email for it",
);
}
}
my $msmtp_conf = "/home/bitrix/.msmtprc";
# create config for msmtp agent
my $msmtp_update = undef;
# if file exists => delete old site's data
if ( -f $msmtp_conf ) {
$msmtp_update = del2msmtp( $site_name, $msmtp_conf );
if ( $msmtp_update->is_error ) { return $msmtp_update }
}
# adding new data to file
$msmtp_update = add2msmtp( $site_name, $site_email_settings, $msmtp_conf );
if ( $msmtp_update->is_error ) { return $msmtp_update }
# update personal apache config fo site
my $apache_conf = $self->site_options->{'ApacheConf'};
my %msmtp_options = ( 'sendmail_path' => 'msmtp -t -i' );
if ( $site_name !~ /^default$/ ) {
$msmtp_options{'sendmail_path'} = qq(msmtp -t -i -a $site_name);
my $update_apache = $self->replace2apache( \%msmtp_options );
if ( $update_apache->is_error ) { return $update_apache; }
}
# create link for cron tasks
my $msmtp_system_conf = "/etc/msmtprc";
if ( ( !-f $msmtp_system_conf ) && ( !-l $msmtp_system_conf ) ) {
symlink $msmtp_conf, $msmtp_system_conf;
}
# update cron if it configured
if ( ( defined $self->site_options->{'CronTask'} )
&& ( $self->site_options->{'CronTask'} =~ /^enable$/ ) )
{
$self->addEmail2Cron();
}
return $self->statusUpdateSite();
}
# disable cron for internal sites tasks
sub disableCronForSite {
my $self = shift;
my $message_p = ( caller(0) )[3];
my $message_t = __PACKAGE__;
my $logOutput = Output->new(
error => 0,
logfile => $self->logfile,
debug => $self->debug
);
my $site_dir = $self->site_dir;
my $site_name = $self->site_name;
my $site_options = $self->site_options;
my $site_status = $site_options->{'SiteStatus'};
if ( ( $site_status =~ /^error$/ ) && ( $site_options->{'error'} < 4 ) ) {
return Output->new(
error => 1,
message =>
"$message_p: Site status=$site_status, not allow manage cron for it",
);
}
my $cron_task = $self->site_options->{'CronTask'};
if ( $cron_task =~ /^disable$/ ) {
return Output->new(
error => 1,
message => "$message_p: Cron is already disabled ",
);
}
my $cron_task_tool = catfile( $site_options->{'DocumentRoot'},
'bitrix/modules/main/tools/cron_events.php' );
my $site_crontab = $self->site_options->{'CronFile'};
$logOutput->log_data("$message_p: update data in $site_crontab");
my $cron_temp = catfile( "/tmp", basename($site_crontab) );
my $cron_replace = 0;
open( my $cth, '>', $cron_temp )
or return Output->new(
error => 1,
message => "$message_p: Cannot open $cron_temp: $!",
);
open( my $cfh, '<', $site_crontab )
or return Output->new(
error => 1,
message => "$message_p: Cannot open $site_crontab: $!",
);
while (<$cfh>) {
s/^\s+//;
s/\s+$//;
my $line = $_;
if ( $line !~ /^#/ && $line =~ m:$cron_task_tool: ) {
$logOutput->log_data("$message_p: found $cron_task_tool");
$line = "#" . $line;
$cron_replace++;
}
print $cth $line, "\n";
}
close $cfh;
close $cth;
if ( $cron_replace > 0 ) {
$logOutput->log_data(
"$message_p: replace $site_crontab by new version");
unlink $site_crontab;
rename $cron_temp, $site_crontab;
chmod 0644, $site_crontab;
}
else {
unlink $cron_temp;
}
return $self->statusUpdateSite();
}
# add email to cron task
sub addEmail2Cron {
my $self = shift;
my $message_p = ( caller(0) )[3];
my $message_t = __PACKAGE__;
my $site_dir = $self->site_dir;
my $site_name = $self->site_name;
my $site_options = $self->site_options;
my $site_status = $site_options->{'SiteStatus'};
my $cron_task = $self->site_options->{'CronTask'};
if ( not defined $site_dir ) {
$site_dir = $site_options->{'DocumentRoot'};
}
if ( not defined $site_name ) { $site_name = "ext_" . basename($site_dir); }
my $site_cron_path =
( $site_options->{'SiteInstall'} =~ /^link$/ )
? $site_options->{'SiteKernelDir'}
: $site_dir;
my $site_mstmtp_str = qq(-d sendmail_path="msmtp -t -i -a $site_name");
my $cron_task_tool =
catfile( $site_cron_path, 'bitrix/modules/main/tools/cron_events.php' );
my $site_crontab =
catfile( '/etc/cron.d', 'bx_' . $self->site_options->{'DBName'} );
if ( $cron_task =~ /^enable$/ ) {
my $cron_file = $self->site_options->{'CronFile'};
my $cron_file_bak = $cron_file . ".bak";
open( my $cf, '<', $cron_file )
or return Output->new(
error => 1,
message => "$message_p: Cannot open $cron_file: $!",
);
open( my $cfb, '>', $cron_file_bak )
or return Output->new(
error => 1,
message => "$message_p: Cannot open $cron_file_bak: $!",
);
my $found = 0;
while ( my $line = <$cf> ) {
chomp $line;
$line =~ s/^\s+//;
$line =~ s/\s+$//;
if ( ( $line !~ /^#/ ) && ( $line =~ m:$cron_task_tool: ) ) {
$line =
qq(* * * * * bitrix test -f $cron_task_tool && { /usr/bin/php $site_mstmtp_str -f $cron_task_tool; } >/dev/null 2>&1\n);
$found = 1;
}
print $cfb $line, "\n";
}
close $cf;
if ( $found == 0 ) {
print $cfb "#\n# cron tasks for site $site_dir db=";
print $cfb $self->site_options->{'DBName'};
print $cfb "\n#\n";
print $cfb
qq(* * * * * bitrix test -f $cron_task_tool && { /usr/bin/php $site_mstmtp_str -f $cron_task_tool; } >/dev/null 2>&1\n);
}
close $cfb;
unlink $cron_file;
rename $cron_file_bak, $cron_file;
}
else {
open( my $sch, '>>', $site_crontab )
or return Output->new(
error => 1,
message => "$message_p: Cannot open $site_crontab: $!",
);
print $sch "#\n# cron tasks for site $site_dir db=";
print $sch $self->site_options->{'DBName'};
print $sch "\n#\n";
print $sch
qq(* * * * * bitrix test -f $cron_task_tool && { /usr/bin/php $site_mstmtp_str -f $cron_task_tool; } >/dev/null 2>&1\n);
close $sch;
}
return $self->statusUpdateSite();
}
# enable cron for internal sites tasks
sub enableCronForSite {
my $self = shift;
my $message_p = ( caller(0) )[3];
my $message_t = __PACKAGE__;
my $logOutput = Output->new(
error => 0,
logfile => $self->logfile,
debug => $self->debug
);
my $site_dir = $self->site_dir;
my $site_name = $self->site_name;
my $site_options = $self->site_options;
my $site_status = $site_options->{'SiteStatus'};
if ( ( $site_status =~ /^error$/ ) && ( $site_options->{'error'} < 4 ) ) {
return Output->new(
error => 1,
message =>
"$message_p: Site status=$site_status, not allow manage cron for it",
);
}
my $cron_task = $self->site_options->{'CronTask'};
if ( $cron_task =~ /^enable$/ ) {
return Output->new(
error => 1,
message => "$message_p: Cron record already enabled in "
. $self->site_options->{'CronFile'},
);
}
if ( not defined $site_dir ) {
$site_dir = $site_options->{'DocumentRoot'};
}
if ( not defined $site_name ) { $site_name = "ext_" . basename($site_dir); }
my $site_mstmtp_str =
( ( defined $site_options->{'SMTPHost'} )
&& ( $site_options->{'SMTPHost'} !~ /^$/ ) )
? qq(-d sendmail_path="msmtp -t -i -a $site_name")
: "";
#print "site_name=$site_name site_dir=$site_dir\n";
$logOutput->log_data("$message_p: enable cron settings for $site_dir");
my $cron_task_tool =
catfile( $site_dir, 'bitrix/modules/main/tools/cron_events.php' );
my $site_crontab =
catfile( '/etc/cron.d', 'bx_' . $self->site_options->{'DBName'} );
open( my $sch, '>>', $site_crontab )
or return Output->new(
error => 1,
message => "$message_p: Cannot open $site_crontab: $!",
);
print $sch "#\n# cron tasks for site $site_dir db=";
print $sch $self->site_options->{'DBName'};
print $sch "\n#\n";
print $sch
qq(* * * * * bitrix test -f $cron_task_tool && { /usr/bin/php $site_mstmtp_str -f $cron_task_tool; } >/dev/null 2>&1\n);
close $sch;
return $self->statusUpdateSite();
}
# disable SSL for site
sub disableSSLForSite {
my $self = shift;
my $site_name = $self->site_name;
my $message_p = ( caller(0) )[3];
my $message_t = __PACKAGE__;
my $logOutput = Output->new(
error => 0,
logfile => $self->logfile,
debug => $self->debug
);
$logOutput->log_data(
"$message_p: disable SSL-ONLY settings for $site_name");
my $site_status = $self->site_options->{'SiteStatus'};
if ( $site_status =~ /^error$/ ) {
my $site_error = $self->site_options->{'error'};
if ( $site_error != 5 ) {
return Output->new(
error => 1,
message =>
"Site $site_name status=$site_status, not allow manage ssl settings for it",
);
}
}
my $https_status = $self->site_options->{'HTTPS'};
if ( $https_status =~ /^disable$/ ) {
return Output->new(
error => 1,
message => "HTTPS-only mode already disabled for $site_name",
);
}
my $site_root = $self->site_options->{'DocumentRoot'};
my $site_ssl_switcher = catfile( $site_root, '.htsecure' );
$logOutput->log_data("$message_p: unlink $site_ssl_switcher");
unlink $site_ssl_switcher;
# restart nginx
my $po = Pool->new();
my $ansData = $po->ansible_conf;
my $cmd_play = $ansData->{'playbook'};
my $cmd_conf = catfile( $ansData->{'base'}, "web.yml" );
my $cmd_opts = { 'manage_web' => 'restart_web' };
my $dh = bxDaemon->new(
debug => $self->debug,
task_cmd => qq($cmd_play $cmd_conf)
);
my $created_process =
$dh->startAnsibleProcess( 'restart_web_services', $cmd_opts );
return $self->statusUpdateSite();
}
# enable SSL-ONLY for site
sub enableSSLForSite {
my $self = shift;
my $site_name = $self->site_name;
my $message_p = ( caller(0) )[3];
my $message_t = __PACKAGE__;
my $logOutput = Output->new(
error => 0,
logfile => $self->logfile,
debug => $self->debug
);
$logOutput->log_data("$message_p: enable SSL-ONLY settings for $site_name");
my $site_status = $self->site_options->{'SiteStatus'};
if ( $site_status =~ /^error$/ ) {
my $site_error = $self->site_options->{'error'};
if ( $site_error != 5 ) {
return Output->new(
error => 1,
message =>
"Site $site_name status=$site_status, not allow manage ssl settings for it",
);
}
}
my $https_status = $self->site_options->{'HTTPS'};
if ( $https_status =~ /^enable$/ ) {
return Output->new(
error => 1,
message => "HTTPS-only mode already enabled for $site_name",
);
}
my $site_root = $self->site_options->{'DocumentRoot'};
my $site_ssl_switcher = catfile( $site_root, '.htsecure' );
open( my $sss, '>', $site_ssl_switcher )
or return Output->new(
error => 1,
message => "$message_p: Can't create $site_ssl_switcher: $!"
);
close $sss;
$logOutput->log_data("$message_p: created $site_ssl_switcher");
# restart nginx
my $po = Pool->new();
my $ansData = $po->ansible_conf;
my $cmd_play = $ansData->{'playbook'};
my $cmd_conf = catfile( $ansData->{'base'}, "web.yml" );
my $cmd_opts = { "manage_web" => "restart_web" };
my $dh = bxDaemon->new(
debug => $self->debug,
task_cmd => qq($cmd_play $cmd_conf)
);
my $created_process =
$dh->startAnsibleProcess( 'restart_web_services', $cmd_opts );
return $self->statusUpdateSite();
}
# enable cron for site services
sub enableCronService {
my ( $self, $service ) = @_;
my $site_name = $self->site_name;
my $site_dir = $self->site_dir;
my $site_options = $self->site_options;
my $site_status = $site_options->{'SiteStatus'};
my $message_p = ( caller(0) )[3];
my $message_t = __PACKAGE__;
my $logOutput = Output->new(
error => 0,
logfile => $self->logfile,
debug => $self->debug
);
if ( not defined $service ) {
return Output->new(
error => 1,
message => "$message_p: You must defined service name"
);
}
if ( ( $site_status =~ /^error$/ ) && ( $site_options->{'error'} < 4 ) ) {
return Output->new(
error => 1,
message =>
"$message_p: Site status=$site_status, not allow manage cron for it",
);
}
my $site_root = $site_options->{'DocumentRoot'};
$logOutput->log_data(
"$message_p: enable start service $service for site in $site_root");
if ( $service !~ /^(xmppd|smtpd)$/ ) {
return Output->new(
error => 1,
message => "$message_p: Service $service is not supported",
);
}
my $cron_services = $self->site_options->{'CronService'};
if ( defined $cron_services->{$service} ) {
return Output->new(
error => 1,
message => "$message_p: Service $service already enabled in "
. $cron_services->{$service}->{'cron'}
);
}
my $service_script = '/opt/webdir/bin/bx_cron_services.sh';
my $site_db = $site_options->{'DBName'};
my $site_crontab = catfile( '/etc/cron.d', 'bx_' . $site_db );
open( my $sh, '>>', $site_crontab )
or return Output->new(
error => 1,
message => "$message_p: Cannot open $site_crontab: $!",
);
print $sh
qq(#\n#auto start service=$service tasks for site in $site_root\n#\n);
print $sh qq(*/5 * * * * root $service_script $service $site_root\n\n);
close $sh;
return Output->new(
error => 0,
message =>
"$message_t: Add task for service $service to $site_crontab for site in $site_root"
);
}
# disable cron for site services
sub disableCronService {
my ( $self, $service ) = @_;
my $message_p = ( caller(0) )[3];
my $message_t = __PACKAGE__;
my $logOutput = Output->new(
error => 0,
logfile => $self->logfile,
debug => $self->debug
);
my $site_dir = $self->site_dir;
my $site_name = $self->site_name;
my $site_options = $self->site_options;
my $site_status = $site_options->{'SiteStatus'};
if ( not defined $service ) {
return Output->new(
error => 1,
message => "$message_p: You must defined service name"
);
}
if ( $service !~ /^(xmppd|smtpd)$/ ) {
return Output->new(
error => 1,
message => "$message_p: Service $service is not supported",
);
}
if ( ( $site_status =~ /^error$/ ) && ( $site_options->{'error'} < 4 ) ) {
return Output->new(
error => 1,
message =>
"$message_p: Site status=$site_status, not allow manage cron for it",
);
}
$logOutput->log_data(
"$message_p: disable start service $service for site in "
. $site_options->{'DocumentRoot'} );
my $cron_services = $site_options->{'CronService'};
if ( not defined $cron_services->{$service} ) {
return Output->new(
error => 1,
message => "$message_p: Service $service already disabled"
);
}
my $site_root = $site_options->{'DocumentRoot'};
my $site_crontab = $cron_services->{$service}->{'cron'};
my $site_util = $cron_services->{$service}->{'util'};
my $site_crontab_tmp = $site_crontab . ".tmp";
open( my $ch, '<', $site_crontab )
or return Output->new(
error => 1,
message => "$message_p: Cannot open $site_crontab: $!"
);
open( my $cn, '>', $site_crontab_tmp )
or return Output->new(
error => 1,
message => "$message_p: Cannot open $site_crontab_tmp: $!"
);
while ( my $line = <$ch> ) {
if ( $line =~ m:$site_util\s+$service\s+$site_root: ) {
$line = "#$line";
}
if ( $line =~ m:$site_util\s*$: ) {
$line = "#$line";
}
print $cn $line;
}
close $cn;
close $ch;
unlink $site_crontab;
rename $site_crontab_tmp, $site_crontab;
return Output->new(
error => 0,
message =>
"$message_t: Delete task for service $service from $site_crontab for site $site_root"
);
}
# Manage composite settings for the site
# enable - create new settings or update existen
# disable - disable nginx settings
sub manageNginxComposite {
my ( $self, $opt ) = @_;
my $site_name = $self->site_name;
my $site_install = $self->site_options->{'SiteInstall'};
my $site_status = $self->site_options->{'SiteStatus'};
my $message_p = ( caller(0) )[3];
my $message_t = __PACKAGE__;
my $logOutput = Output->new(
error => 0,
logfile => $self->logfile,
debug => $self->debug
);
if ( ( $site_install =~ /^$/ ) && ( $site_status =~ /^error$/ ) ) {
return Output->new(
error => 1,
message => "$message_p: Not found site=$site_name on the server",
);
}
if ( $site_install =~ /^ext_kernel$/ ) {
return Output->new(
error => 1,
message =>
"$message_p: Site=$site_name hasn't nginx configs. Nothing to do.",
);
}
my $a_opts = {
web_site_name => $site_name,
manage_web => 'composite',
};
if ( $opt =~ /^enable$/ ) {
$a_opts->{'manage_web'} = 'enable_composite';
}
elsif ( $opt =~ /^disable$/ ) {
$a_opts->{'manage_web'} = 'disable_composite';
}
else {
return Output->new(
error => 1,
message =>
"$message_p: You can usage only enable or disable actions"
);
}
$logOutput->log_data("$message_p: start $opt fo site_name=$site_name");
# create site by ansible task
my $po = Pool->new();
my $ansData = $po->ansible_conf;
my $cmd_play = $ansData->{'playbook'};
my $cmd_conf = catfile( $ansData->{'base'}, "web.yml" );
my $dh = bxDaemon->new(
debug => $self->debug,
task_cmd => qq($cmd_play $cmd_conf)
);
my $created_process = $dh->startAnsibleProcess( "site_composite", $a_opts );
return $created_process;
}
# Manage Site options
sub siteOptions {
my ( $self, $opt, $val ) = @_;
my $site_name = $self->site_name;
my $site_install = $self->site_options->{'SiteInstall'};
my $site_status = $self->site_options->{'SiteStatus'};
my $message_p = ( caller(0) )[3];
my $message_t = __PACKAGE__;
my $logOutput = Output->new(
error => 0,
logfile => $self->logfile,
debug => $self->debug
);
if ( ( $site_install =~ /^$/ ) && ( $site_status =~ /^error$/ ) ) {
return Output->new(
error => 1,
message => "$message_p: Not found site=$site_name on the server",
);
}
if ( $site_install =~ /^ext_kernel$/ ) {
return Output->new(
error => 1,
message =>
"$message_p: Site=$site_name hasn't nginx configs. Nothing to do.",
);
}
my $a_opts = {
web_site_name => $site_name,
option => $opt,
value => $val,
manage_web => 'site_options',
};
$logOutput->log_data("$message_p: start $opt fo site_name=$site_name");
# create site by ansible task
my $po = Pool->new();
my $ansData = $po->ansible_conf;
my $cmd_play = $ansData->{'playbook'};
my $cmd_conf = catfile( $ansData->{'base'}, "web.yml" );
my $dh = bxDaemon->new(
debug => $self->debug,
task_cmd => qq($cmd_play $cmd_conf)
);
my $created_process = $dh->startAnsibleProcess( "site_options", $a_opts );
return $created_process;
}
# Manage certificates by LE
1;