Your IP : 3.145.155.254
Current Path : /opt/webdir/lib/ |
|
Current File : //opt/webdir/lib/Host.pm |
package Host;
use Moose;
use File::Basename qw( dirname basename );
use File::Spec::Functions;
use Data::Dumper;
use Output;
use JSON;
use Pool;
use bxInventory qw( get_from_yaml save_to_yaml );
has 'host', is => 'ro', isa => 'Str';
has 'ip', is => 'ro', isa => 'Str', lazy => 1, builder => 'get_ipaddress';
has 'debug', is => 'ro', lazy => 1, default => 0;
has 'logfile', is => 'ro', default => '/opt/webdir/logs/host_manage.debug';
# test if host with hostname in the pool
# 1 -> pool_not_created
# 2 -> host_not_in_pool
# 3 -> host_in_pool_not_in_group
# 0 -> host_in_pool
sub host_in_pool {
my ( $self, $group, $hostname ) = @_;
if ( not defined $hostname ) {
$hostname = $self->host;
}
$hostname =~ s/^["']//;
$hostname =~ s/["']$//;
my $message_p = ( caller(0) )[3];
my $message_t = __PACKAGE__;
my $debug = $self->debug;
my $logOutput = Output->new( error => 0, logfile => $self->logfile );
my %returnMessage = (
1 => 'pool_not_created',
2 => 'host_not_in_pool',
3 => 'host_in_pool_not_in_group',
0 => 'host_in_group',
);
my $rt = 0;
my $pool = Pool->new();
my $getConfigData = $pool->get_ansible_data;
if ( $getConfigData->is_error > 0 ) {
$rt = 1;
if ($debug) { $logOutput->log_data("$message_p: pool is not created"); }
}
else {
if ($debug) {
$logOutput->log_data(
"$message_p: pool exists, try found host $hostname");
}
# get all data for hosts in the pool
my $configData = $getConfigData->get_data;
my $configHostData = $configData->[1]->{$hostname};
# no host :(
if ( !$configHostData ) {
$rt = 2;
if ($debug) {
$logOutput->log_data(
"$message_p: host $hostname not found in pool");
}
# host found
}
else {
# if group set => we need check group
if ( $group && $group !~ /^hosts$/ ) {
my $host_groups =
grep( /^$group$/, keys %{ $configHostData->{'roles'} } );
# roles not found = group not found
if ( $host_groups == 0 ) {
if ($debug) {
$logOutput->log_data(
"$message_p: host $hostname not found in $group");
}
$rt = 3;
}
}
}
}
if ($debug) {
$logOutput->log_data(
"$message_p: search finished, " . $returnMessage{$rt} );
}
return Output->new( error => $rt, message => $returnMessage{$rt} );
}
sub onfly_host_test {
my $self = shift;
my $shortname = shift;
my $netaddr = shift;
my $ipaddr = $netaddr;
if ( $netaddr !~ /^[\d\.]+$/ ) {
my $bx_net = bxNetwork->new( netaddr => $netaddr, host => $shortname );
$ipaddr = $bx_net->a_lookup($netaddr);
}
my $message_p = ( caller(0) )[3];
my $message_t = __PACKAGE__;
my $debug = $self->debug;
my $logOutput = Output->new( error => 0, logfile => $self->logfile );
if ($debug) { $logOutput->log_data("$message_p: start testing"); }
my $pool = Pool->new();
my $conf_data = $pool->get_ansible_data();
my $ans_data = $pool->set_ansible_conf();
if ( $conf_data->is_error ) { return $conf_data }
my @servers = sort keys %{ $conf_data->get_data->[1] };
if ($debug) {
$logOutput->log_data( "$message_p: found " . join( ',', @servers ) );
}
my $cmd_exec = $ans_data->{'ansible'};
my $cmd_module = 'bx_vat';
my $cmd_library = $ans_data->{'library'};
foreach my $server (@servers) {
if ($debug) {
$logOutput->log_data("$message_p: process server $server");
}
my $cmd_run =
qq($cmd_exec $server -m "$cmd_module" -M "$cmd_library" 2>/dev/null);
open( my $rh, "$cmd_run |" ) or next;
my $json_output = "";
while (<$rh>) {
if (/^$server\s*\|\s*(\S+)\s*\>\>\s*\{\s*/) {
my $result = $1;
if ( $result =~ /^success$/i ) {
$json_output = $json_output . "\{";
next;
}
}
if ( $json_output !~ /^$/ ) {
$json_output = $json_output . $_;
}
}
close $rh;
#print "|$json_output|\n";
if ( $json_output !~ /^$/ ) {
my $ansible_facts = from_json($json_output);
my $server_info = $ansible_facts->{'ansible_facts'};
for my $addr_info ( grep /^addr/, keys %$server_info ) {
my $addr_ip = $server_info->{$addr_info};
if ( $addr_ip =~ /^$ipaddr$/ ) {
my $int = $addr_info;
$int =~ s/^addr_//;
return Output->new(
error => 1,
message =>
"$message_t: $server already in the pool (ip=$addr_ip interface=$int)",
);
}
}
}
}
return Output->new(
error => 0,
message => "$message_t: $ipaddr not found"
);
}
# get info from ansible config
sub get_ipaddress {
my $self = shift;
my $hostname = $self->host;
my $message_p = ( caller(0) )[3];
my $message_t = __PACKAGE__;
my $debug = $self->debug;
my $logOutput = Output->new( error => 0, logfile => $self->logfile );
my $test_host = $self->host_in_pool;
my $ipaddres = '';
if ($debug) {
$logOutput->log_data("$message_p: try found netaddress for $hostname");
}
# pool is not created = imossible, but :)
if ( $test_host->is_error == 1 ) {
if ($debug) {
$logOutput->log_data(
"$message_p: test host in the pool return error");
}
return $hostname;
# host not in the pool: get address from DNS server
}
elsif ( $test_host->is_error == 2 or $test_host->is_error == 3 ) {
my $bx_n = bxNetwork->new( host => $hostname );
my $bx_net_info = $bx_n->network_info;
if ( $bx_net_info->is_error ) {
if ($debug) {
$logOutput->log_data(
"$message_p: search netaddress by hostname return error");
}
return $hostname;
}
$ipaddres = $bx_net_info->get_data->[1]->{'netaddr'};
if ($debug) {
$logOutput->log_data(
"$message_p: host=$hostname netaddr=$ipaddres");
}
# get address from pool configuration
}
else {
my $bx_pool = Pool->new();
my $bx_data = $bx_pool->get_ansible_data;
my $bx_conf = $bx_data->get_data;
$ipaddres = $bx_conf->[1]->{$hostname}->{'ip'};
if ($debug) {
$logOutput->log_data(
"$message_p: host=$hostname netaddr=$ipaddres");
}
}
#print $ipaddres,"\n";
return $ipaddres;
}
sub get_bx_dbs {
my $self = shift;
my $message_p = ( caller(0) )[3];
my $message_t = __PACKAGE__;
my $hostname = Pool::esc_chars( $self->host );
my $pool = Pool->new();
my $ansData = $pool->set_ansible_conf();
my $cmd_play = $ansData->{'ansible'};
my $cmd_module = 'bx_db';
my $cmd_library = $ansData->{'library'};
my $cmd_run = qq($cmd_play $hostname -m "$cmd_module" -M "$cmd_library");
open( my $rh, "$cmd_run |" )
or return Output->new(
error => 1,
message => "$message_p: Cannot run $cmd_module on $hostname",
);
my $json_output = "";
while (<$rh>) {
if (/^$hostname\s*\|\s*(\S+)\s*\>\>\s*\{\s*/) {
my $result = $1;
if ( $result =~ /^success$/i ) {
$json_output = $json_output . "\{";
next;
}
else {
return Output->new(
error => 1,
message => "$message_p: \`$cmd_run\` return $result",
);
}
}
if ( $json_output !~ /^$/ ) {
$json_output = $json_output . $_;
}
}
close $rh;
my $ansible_facts = from_json($json_output);
my $server_info = $ansible_facts->{'ansible_facts'};
return Output->new(
error => 0,
data => [ 'dbs_list', { $hostname => $server_info } ],
);
}
sub get_bx_info {
my $self = shift;
my $message_p = ( caller(0) )[3];
my $message_t = __PACKAGE__;
my $hostname = Pool::esc_chars( $self->host );
my $pool = Pool->new();
my $ansData = $pool->set_ansible_conf();
my $cmd_play = $ansData->{'ansible'};
my $cmd_module = 'bx_vat';
my $cmd_library = $ansData->{'library'};
my $cmd_run =
qq($cmd_play $hostname -m "$cmd_module" -M "$cmd_library" 2>&1);
#print "$cmd_run\n";
open( my $rh, "$cmd_run |" )
or return Output->new(
error => 1,
message => "$message_p: Cannot run $cmd_module on $hostname",
);
my $json_output = "";
my $erro_output = "";
while (<$rh>) {
if ( /^$hostname\s*\|\s*(\S+)\s*\>\>\s*\{\s*/
or /^$hostname\s*\|\s*(\S+)\s*=\>(.*)$/ )
{
my $result = $1;
my $opt = ($2) ? $2 : "";
$opt =~ s/^\s+//;
$opt =~ s/\s+$//;
if ( $result =~ /^success$/i ) {
$json_output = $json_output . "\{";
next;
# vm03 | FAILED => SSH Error: ssh:
}
else {
return Output->new(
error => 1,
message => "$message_p: $opt",
);
}
}
elsif (/^No hosts matched$/) {
return Output->new(
error => 1,
message => "$message_p: Not found $hostname in the pool",
);
}
if ( $json_output !~ /^$/ ) {
$json_output = $json_output . $_;
}
}
close $rh;
my $ansible_facts = from_json($json_output);
my $server_info = $ansible_facts->{'ansible_facts'};
return Output->new(
error => 0,
data => [ 'bx_variables', { $hostname => $server_info } ],
);
}
# update data in the host vars file
sub update_host_vars {
my $self = shift;
my $options = shift;
my $message_p = ( caller(0) )[3];
my $message_t = __PACKAGE__;
# test if host exists
my $host = $self->host;
#print "1. test hot in pool\n";
my $host_status = $self->host_in_pool();
#print Dumper($host_status);
if ( $host_status->is_error ) {
return $host_status;
}
if ( not defined $options ) {
return Output->new(
error => 1,
message => "$message_p: Need defined hash with options list"
);
}
# get pool information
my $bx_pool = Pool->new();
my $an_data = $bx_pool->ansible_conf;
my $host_vars_path = catfile( $an_data->{'host_vars'}, $host );
my $host_vars_temp = $host_vars_path . ".temp";
my $host_vars_live = ( -f $host_vars_path ) ? 1 : 0;
my $inventory_data;
if ($host_vars_live){
my $get_inventory = get_from_yaml($host_vars_path);
if ( $get_inventory->is_error ) {
return $get_inventory;
}
$inventory_data = $get_inventory->data->[1];
}
##print "2. create updated and deleted options hash\n";
# return structure
my $updates = 0;
my $deletes = 0;
foreach my $k ( keys %$options ) {
next if ($k =~ /^(group|state|hostname)$/);
#print "$k => $options->{$k}\n";
# key=value
if (defined $options->{$k}){
if (defined $inventory_data->{$k}){
if ($inventory_data->{$k} ne $options->{$k}){
$inventory_data->{$k} = $options->{$k};
$updates++;
}
}
else {
$inventory_data->{$k} = $options->{$k};
$updates++;
}
}
# key
else {
if (defined $inventory_data->{$k}){
delete $inventory_data->{$k};
$deletes++;
}
}
}
# update values or create new
my $save_inventory = save_to_yaml($inventory_data, $host_vars_temp);
if ( $save_inventory->is_error ) {
return $save_inventory;
}
# rewrite origin file
unlink $host_vars_path if ($host_vars_live);
rename $host_vars_temp, $host_vars_path;
chmod 0640, $host_vars_path;
return Output->new(
error => 0,
message => "$message_p: "
. "File=$host_vars_path is modified; updates=$updates deletes=$deletes",
data => ["$message_p",
{updates => $updates, deletes => $deletes, file => $host_vars_path}]
);
}
# add host to group, if group not defined add host to pool
sub add_to_group {
my ( $self, $group, $is_update ) = @_;
if ( not defined $is_update ) {
$is_update = 0;
}
my $message_p = ( caller(0) )[3];
my $message_t = __PACKAGE__;
my $debug = $self->debug;
my $logOutput = Output->new( error => 0, logfile => $self->logfile );
my $hostname = $self->host;
my $ipaddres = $self->ip;
my $mess = ( defined $group ) ? "$group" : "hosts";
if ($debug) {
$logOutput->log_data("$message_p: start add host $hostname to $mess");
}
# create hostname if request by IP
if ( $mess =~ /^hosts$/ && $hostname =~ /^$ipaddres$/ ) {
# get localhost hostname and ip address
my $bx_n = bxNetwork->new( netaddr => $hostname );
my $bx_net_info = $bx_n->network_info;
if ( $bx_net_info->is_error ) { return $bx_net_info; }
$hostname = $bx_net_info->get_data->[1]->{'host'};
$ipaddres = $bx_net_info->get_data->[1]->{'netaddr'};
if ($debug) {
$logOutput->log_data(
"$message_p: update hostname=$hostname netaddr=$ipaddres");
}
}
my $status = $self->host_in_pool( $group, $hostname );
## 0 => host exists in defined group
if ( !$status->is_error ) {
if ($debug) {
$logOutput->log_data("$message_p: host $hostname in $mess");
}
return Output->new(
error => 0,
message => "$message_p: $hostname already in $mess",
);
}
## 1 => pool is not created
if ( $status->is_error == 1 ) {
if ($debug) { $logOutput->log_data("$message_p: pool is not created"); }
return $status;
}
my $pool = Pool->new();
my $ansData = $pool->set_ansible_conf();
my $bxData = $pool->set_bitrix_conf();
my $cfgData = $pool->get_ansible_data();
my $mStatus = $pool->monitorStatus()->get_data()->[1]->{monitoring_status};
#print Dumper($cfgData);
my $section_prefix = $bxData->{'aHostsPrefix'};
# create updated_groups
my %updated_groups;
if ( defined $group ) {
$updated_groups{$group} = 0;
}
# 2 => host not in main group hosts ( update $group and hosts)
if ( $status->is_error == 2 ) {
$updated_groups{ $bxData->{'aHostsDefault'} } = 0;
if ($debug) {
$logOutput->log_data(
"$message_p: need add $hostname to hosts group");
}
}
# add host to group(s):
my $ans_hosts_path = $ansData->{'hosts'};
my $ans_hosts_temp = $ans_hosts_path . ".tmp";
open( my $hh, $ans_hosts_path )
or return Output->new(
error => 2,
message => "$message_p: Cannot open $ans_hosts_path: $!"
);
open( my $th, ">$ans_hosts_temp" )
or return Output->new(
error => 2,
message => "$message_p: Cannot open $ans_hosts_temp: $!"
);
# create temporary file with new data
while (<$hh>) {
s/^\s+//;
s/\s+$//;
print $th $_, "\n";
if (/^\[$section_prefix\-([^\]]+)\]$/) {
my $found = $1;
if ( grep /^$found$/, keys %updated_groups ) {
print $th "$hostname ansible_ssh_host=$ipaddres\n";
$updated_groups{$found} = 1;
if ($debug) {
$logOutput->log_data("$message_p: add host to $found");
}
}
}
}
close $hh;
close $th;
# test if all updates done
foreach my $k ( keys %updated_groups ) {
if ( $updated_groups{$k} == 0 ) {
if ($debug) {
$logOutput->log_data("$message_p: not updated $k. exit");
}
return Output->new(
error => 1,
message => "$message_p: Cannot update group $k",
);
}
}
# create backup for current config and replace it by temporary file
if ( $is_update == 0 ) {
unlink $ans_hosts_path;
rename $ans_hosts_temp, $ans_hosts_path;
# run common playbook
# set network, time
my $cmd_play = $ansData->{'playbook'};
my $cmd_conf = catfile( $ansData->{'base'}, "common.yml" );
my $cmd_type = "common";
if ( defined $mStatus && $mStatus eq "enable" ) {
$cmd_conf = catfile( $ansData->{'base'}, "monitor.yml" );
$cmd_type = "monitor";
}
# run as daemon in background
my $dh = bxDaemon->new( task_cmd => qq($cmd_play $cmd_conf) );
if ($debug) {
$logOutput->log_data(
"$message_p: start common task for new $hostname");
}
my $created_process = $dh->startProcess($cmd_type)->get_data()->[1];
my ($task_id) = grep {!/^task_name$/} keys %$created_process;
my $task_pid = $created_process->{$task_id}->{pid};
my $task_status = $created_process->{$task_id}->{status};
return Output->new(
error => 0,
message => "$message_p: succefully added $hostname to group(s)",
data => [ 'hosts_file', $ans_hosts_path, [$task_id, $task_pid, $task_status] ]
);
}
else {
if ($debug) {
$logOutput->log_data(
"$message_p: succefully added $hostname to group(s)");
}
return Output->new(
error => 0,
message => "$message_p: succefully added $hostname to group(s)",
data => [ 'hosts_file', $ans_hosts_temp ]
);
}
}
# delete host from group, if group not defined - delete from all pool groups
# 1 => 'pool_not_created',
# 2 => 'host_not_in_pool',
# 3 => 'host_in_pool_not_in_group',
# 0 => 'host_in_group',
sub del_from_group {
my $self = shift;
my $group = shift;
my $message_p = ( caller(0) )[3];
my $message_t = __PACKAGE__;
my $debug = $self->debug;
my $logOutput = Output->new( error => 0, logfile => $self->logfile );
my $hostname = $self->host;
# test if host in the pool
my $status = $self->host_in_pool($group);
my $mess = ( defined $group ) ? "$group" : "hosts";
if ( $status->is_error ) {
return Output->new(
error => 0,
message => "$message_p: $hostname not found in group $mess"
);
}
# get pool configuration
my $bx_pool = Pool->new();
my $ans_conf = $bx_pool->set_ansible_conf();
my $bx_conf = $bx_pool->set_bitrix_conf();
my $pool_conf = $bx_pool->get_ansible_data();
if ( $pool_conf->is_error ) { return $pool_conf; }
# test if host hold roles
my $host_conf = $pool_conf->get_data->[1]->{$hostname};
my @host_roles = sort keys %{ $host_conf->{'roles'} };
my $host_roles = @host_roles;
if ( $mess =~ /^hosts$/ && $host_roles > 0 ) {
return Output->new(
error => 1,
message =>
"$message_t: Cannot delete host $hostname, it hold next roles: "
. join( ', ', @host_roles )
);
}
# group names options
my $section_prefix = $bx_conf->{'aHostsPrefix'};
my $section_default = $bx_conf->{'aHostsDefault'};
# ansible playbook settings
my $cmd_play = $ans_conf->{'playbook'};
my $cmd_conf = catfile( $ans_conf->{'base'}, "common.yml" );
# remove ssh options from server is main group
if ( $mess =~ /^hosts$/ ) {
my $cmd_opt = "common_server=$hostname common_manage=remove";
my $cmd_run = qq($cmd_play $cmd_conf -e "$cmd_opt" 1>/dev/null 2>&1);
system($cmd_run) == 0
or return Output->new(
error => 1,
message =>
"$message_p: Cannot remove ssh options from host $hostname",
);
}
# delete host from group
my $ans_hosts_path = $ans_conf->{'hosts'};
my $ans_hosts_temp = $ans_hosts_path . ".tmp";
open( my $hh, $ans_hosts_path )
or return Output->new(
error => 1,
message => "$message_p: Cannot open $ans_hosts_path: $!"
);
open( my $th, ">$ans_hosts_temp" )
or return Output->new(
error => 1,
message => "$message_p: Cannot open $ans_hosts_temp: $!"
);
# create temporary file with new data
# if group defined = > delete only from this group
# else delete from all group in the pool
my $pool_config_changed = 0;
my $section_name = "";
my $is_deleted_section = 0;
while (<$hh>) {
chomp;
s/^\s+//;
s/\s+$//;
my $str = $_;
# section pool is found
if ( $str =~ /^\[$section_prefix-([^\]]+)\]/ ) {
$section_name = $1;
$is_deleted_section = 1; # default delete
# change opinion about the removal
if ( $group
&& $group !~ /^$section_default$/
&& $section_name !~ /^$group$/ )
{
$is_deleted_section = 0;
}
}
# option found
if ( /^$hostname\s+(.+)$/ && $is_deleted_section == 1 ) {
$pool_config_changed++;
next;
}
print $th $_, "\n";
}
close $hh;
close $th;
if ( $pool_config_changed == 0 ) {
return Output->new(
error => 3,
message => "$message_p: Cannot delete host from the group $mess"
);
}
# backup and rename
rename $ans_hosts_path, $ans_hosts_path . ".bak";
rename $ans_hosts_temp, $ans_hosts_path;
# update security option on hosts that left in the pool
my $dh = bxDaemon->new( task_cmd => qq($cmd_play $cmd_conf) );
my $created_process = $dh->startProcess('common');
return Output->new(
error => 0,
message => "$message_p: successful deleted host $hostname from pool"
);
}
sub removeHostFromPool {
my $self = shift;
my $message_p = ( caller(0) )[3];
my $message_t = __PACKAGE__;
my $debug = $self->debug;
my $logOutput = Output->new( error => 0, logfile => $self->logfile );
my $hostname = $self->host;
# test if host in the pool
my $status = $self->host_in_pool();
if ( $status->is_error ) {
return Output->new(
error => 0,
message => "$message_p: $hostname not found in the pool."
);
}
# get pool configuration
my $bx_pool = Pool->new();
my $ans_conf = $bx_pool->set_ansible_conf();
my $pool_conf = $bx_pool->get_ansible_data();
if ( $pool_conf->is_error ) { return $pool_conf; }
# test if host hold roles
my $host_conf = $pool_conf->get_data->[1]->{$hostname};
my @host_roles = sort keys %{ $host_conf->{'roles'} };
my $host_roles = @host_roles;
if ( $host_roles > 0 ) {
return Output->new(
error => 1,
message =>
"$message_t: Cannot delete host $hostname, it hold next roles: "
. join( ', ', @host_roles )
);
}
# ansible playbook settings
my $cmd_play = $ans_conf->{'playbook'};
my $cmd_conf = catfile( $ans_conf->{'base'}, "common.yml" );
# clean up ssh configuration, ansible variables and etc,
my $opts = {
common_server => $hostname,
common_manage => 'remove',
};
my $dh = bxDaemon->new(
debug => $self->debug,
task_cmd => qq($cmd_play $cmd_conf)
);
my $created_process = $dh->startAnsibleProcess( "remove_$hostname", $opts );
return $created_process;
}
# create host in the pool
sub createHost {
my $self = shift;
my $message_p = ( caller(0) )[3];
my $message_t = __PACKAGE__;
my $debug = $self->debug;
my $logOutput = Output->new( error => 0, logfile => $self->logfile );
my $err_regexp = '(localhost|127\.0\.0\.\d+|localhost.localdomain)';
my $hostname = $self->host;
my $ipaddres = $self->ip;
if (not defined $hostname){
return Output->new(
error => 1,
message => "Cannot use empty hostname"
)
}
if ($debug) {
$logOutput->log_data(
"$message_p: start created host hostname=$hostname netaddr=$ipaddres"
);
}
# if user try add host=127.0.0.1 => ERROR
if ( $hostname =~ /^$err_regexp$/ || $ipaddres =~ /^$err_regexp$/ ) {
if ($debug) {
$logOutput->log_data(
"$message_p: cannot add to pool hostname=$hostname netaddr=$ipaddres"
);
}
return Output->new(
error => 1,
message => "$message_p: cannot use $hostname for add",
);
}
# generate host options
my $po = Pool->new();
my $host_id = $po->generate_host_id;
my $host_pass = $po->generate_host_password($hostname);
my $options = {
group => 'hosts',
host_id => $host_id,
host_pass => $host_pass,
bx_hostname => $hostname,
bx_netaddr => $ipaddres,
bx_connect => 'ipv4',
bx_netname => $hostname,
};
#print Dumper($options);
# if user input the same netaddress and hostname
# case1: hostname=example.org and ipaddress=example.org
# case2: hostname=1.2.3.4 ipaddres=1.2.3.4
if ( $hostname =~ /^$ipaddres$/ ) {
# case1: example.org
if ( $hostname !~ /^[\d\.]+$/ ) {
# get ipaddress
my $bx_n = bxNetwork->new( netaddr => $ipaddres );
$options->{'bx_netaddr'} = $bx_n->a_lookup($hostname);
if ( $options->{'bx_netaddr'} =~ /^$/ ) {
return Output->new(
error => 1,
message => "$message_p: $hostname is not a valid DNS name",
);
}
$options->{'bx_connect'} = 'fqdn';
# case2: 1.2.3.4 - we must defined correct hostname and ident for host
}
else {
my $bx_n = bxNetwork->new( netaddr => $ipaddres );
my $bx_net_info = $bx_n->network_info;
if ( $bx_net_info->is_error ) { return $bx_net_info; }
my $bx_net_data = $bx_net_info->get_data->[1];
my $type = $bx_net_data->{'type'};
if ( $type =~ /^fqdn$/ ) {
$options->{'bx_hostname'} = $bx_net_data->{'netaddr'};
$options->{'bx_netname'} = $bx_net_data->{'netaddr'};
}
else {
$options->{'bx_hostname'} = $bx_net_data->{'host'};
$options->{'bx_netname'} = $bx_net_data->{'host'};
}
if ($debug) {
$logOutput->log_data(
"$message_p: change hostname=$hostname to "
. $options->{'bx_netname'} );
}
}
# hostname=example ip=example.org
# or
# hostname example ip=1.2.3.4
}
else {
#$options->{'bx_hostname'} =~ s/^([^\.]+)\..+/$1/;
# test fqdn name: example.org
if ( $ipaddres !~ /^[\d\.]+$/ ) {
my $bx_n = bxNetwork->new( netaddr => $ipaddres );
$options->{'bx_netaddr'} = $bx_n->a_lookup($ipaddres);
if ( $options->{'bx_netaddr'} =~ /^$/ ) {
return Output->new(
error => 1,
message => "$message_p: $ipaddres is not a valid DNS name",
);
}
$options->{'bx_connect'} = 'fqdn';
$options->{'bx_netname'} = $ipaddres;
}
}
my $new_host = Host->new(
host => $options->{'bx_hostname'},
ip => $options->{'bx_netaddr'}
);
# test instance by its working option (not saved in the config files)
#my $test_all_host_ints = $new_host->onfly_host_test($hostname, $ipaddres);
#if ($test_all_host_ints->is_error){ return $test_all_host_ints };
# add host to group if one defined
my $group_mod = "no";
my $update_group = $new_host->add_to_group( $options->{'group'} );
if ($debug) { $logOutput->log_data("$message_p: add host to group hosts"); }
my $update_group_data = $update_group->get_data();
my $task_id = "";
my $task_pid = 0;
my $task_status = "";
if (defined $update_group_data->[2]){
$task_id = $update_group_data->[2]->[0];
$task_pid = $update_group_data->[2]->[1];
$task_status = $update_group_data->[2]->[2];
}
if ( $update_group->is_error ) {
return $update_group;
}
$group_mod = "yes";
#print Dumper($new_host);
my $host_mod = "no";
my $update_host = $new_host->update_host_vars($options);
#print Dumper($update_host);
if ( $update_host->is_error ) {
return $update_host;
}
if ($debug) { $logOutput->log_data("$message_p: update host vars"); }
$host_mod = "yes";
return Output->new(
error => 0,
message =>
"$message_p: modification was successful,"
. " host_vars=$host_mod, hosts=$group_mod"
. " task_id=$task_id task_pid=$task_pid task_status=$task_status",
data => [ $message_p, { hosts => $group_mod, host_vars => $host_mod } ]
);
}
# update host info by defined options
sub updateHost {
my $self = shift;
my $options = shift;
my $message_p = ( caller(0) )[3];
my $message_t = __PACKAGE__;
# test if host exists
my $host = $self->host;
# add host to group if one defined
my $group_mod = "no";
if ( defined $options->{'group'} ) {
my $update_group = $self->add_to_group( $options->{'group'} );
if ( $update_group->is_error ) {
return $update_group;
}
$group_mod = "yes";
}
# update additional variables if it defined
#print Dumper($options);
my $plus_option = grep( !/^(state|group|hostname)$/, keys %$options );
my $host_mod = "no";
if ( $plus_option > 0 ) {
my $update_host = $self->update_host_vars($options);
if ( $update_host->is_error ) {
return $update_host;
}
$host_mod = "yes";
}
return Output->new(
error => 0,
message =>
"$message_p: modification was successful, host_vars=$host_mod, hosts=$group_mod",
data => [ $message_p, { hosts => $group_mod, host_vars => $host_mod } ]
);
}
# delete host from group
sub deleteHost {
my $self = shift;
my $options = shift;
my $message_p = ( caller(0) )[3];
my $message_t = __PACKAGE__;
# test if host exists
my $group_mod = "no";
if ( defined $options->{'group'} ) {
my $update_group = $self->del_from_group( $options->{'group'} );
if ( $update_group->is_error ) {
return $update_group;
}
$group_mod = "yes";
}
# update additional variables if it defined
my $plus_option = grep( !/^(state|group|hostname)$/, keys %$options );
my $host_mod = "no";
if ( $plus_option > 0 ) {
my $update_host = $self->update_host_vars($options);
if ( $update_host->is_error ) {
return $update_host;
}
$host_mod = "yes";
}
return Output->new(
error => 0,
message =>
"$message_p: modification was successful, host_vars=$host_mod, hosts=$group_mod",
data => [ $message_p, { hosts => $group_mod, host_vars => $host_mod } ]
);
}
1;