|
|
|
#!/usr/bin/perl
|
|
|
|
|
|
|
|
use strict;
|
|
|
|
use warnings;
|
|
|
|
use Data::Dumper;
|
|
|
|
use Text::Diff;
|
|
|
|
use Anvil::Tools;
|
|
|
|
|
|
|
|
my $THIS_FILE = ($0 =~ /^.*\/(.*)$/)[0];
|
|
|
|
my $running_directory = ($0 =~ /^(.*?)\/$THIS_FILE$/)[0];
|
|
|
|
if (($running_directory =~ /^\./) && ($ENV{PWD}))
|
|
|
|
{
|
|
|
|
$running_directory =~ s/^\./$ENV{PWD}/;
|
|
|
|
}
|
|
|
|
|
|
|
|
# Turn off buffering so that the pinwheel will display while waiting for the SSH call(s) to complete.
|
|
|
|
$| = 1;
|
|
|
|
|
|
|
|
my $anvil = Anvil::Tools->new();
|
|
|
|
|
|
|
|
# Read switches
|
|
|
|
$anvil->Get->switches({list => [], man => $THIS_FILE});
|
|
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => $anvil->data->{switches}});
|
|
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, secure => 0, key => "log_0115", variables => { program => $THIS_FILE }});
|
|
|
|
|
|
|
|
# We'll try to connect in case we're adding additional peers.
|
|
|
|
$anvil->Database->connect({debug => 3});
|
|
|
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, secure => 0, key => "log_0132"});
|
|
|
|
|
|
|
|
#print "DBs: [".$anvil->data->{sys}{database}{connections}."]\n";
|
|
|
|
|
|
|
|
$anvil->data->{network_manager}{want}{ifn1_link1}{mac_address} = "52:54:00:d3:19:cc";
|
|
|
|
$anvil->data->{network_manager}{want}{ifn1_link1}{device} = "enp1s0";
|
|
|
|
$anvil->data->{network_manager}{want}{ifn1_link1}{found} = 0;
|
|
|
|
$anvil->data->{network_manager}{want}{ifn1_link2}{mac_address} = "52:54:00:fc:82:b0";
|
|
|
|
$anvil->data->{network_manager}{want}{ifn1_link2}{device} = "enp7s0";
|
|
|
|
$anvil->data->{network_manager}{want}{ifn1_link2}{found} = 0;
|
|
|
|
|
|
|
|
$anvil->data->{network_manager}{want}{bcn1_link1}{mac_address} = "52:54:00:86:f5:1d";
|
|
|
|
$anvil->data->{network_manager}{want}{bcn1_link1}{device} = "enp8s0";
|
|
|
|
$anvil->data->{network_manager}{want}{bcn1_link1}{found} = 0;
|
|
|
|
$anvil->data->{network_manager}{want}{bcn1_link2}{mac_address} = "52:54:00:16:c5:33";
|
|
|
|
$anvil->data->{network_manager}{want}{bcn1_link2}{device} = "enp9s0";
|
|
|
|
$anvil->data->{network_manager}{want}{bcn1_link2}{found} = 0;
|
|
|
|
|
|
|
|
$anvil->data->{network_manager}{want}{sn1_link1}{mac_address} = "52:54:00:37:6f:22";
|
|
|
|
$anvil->data->{network_manager}{want}{sn1_link1}{device} = "enp10s0";
|
|
|
|
$anvil->data->{network_manager}{want}{sn1_link1}{found} = 0;
|
|
|
|
$anvil->data->{network_manager}{want}{sn1_link2}{mac_address} = "52:54:00:2f:02:1b";
|
|
|
|
$anvil->data->{network_manager}{want}{sn1_link2}{device} = "enp11s0";
|
|
|
|
$anvil->data->{network_manager}{want}{sn1_link2}{found} = 0;
|
|
|
|
|
|
|
|
$anvil->data->{sys}{reboot_needed} = 0;
|
|
|
|
|
|
|
|
scan($anvil);
|
|
|
|
|
|
|
|
reconfigure($anvil);
|
|
|
|
|
|
|
|
|
|
|
|
$anvil->nice_exit({exit_code => 0});
|
|
|
|
|
|
|
|
#############################################################################################################
|
|
|
|
# Functions #
|
|
|
|
#############################################################################################################
|
|
|
|
|
|
|
|
sub reconfigure
|
|
|
|
{
|
|
|
|
my ($anvil) = @_;
|
|
|
|
|
|
|
|
my $reconfigure_count = keys %{$anvil->data->{network_manager}{reconfigure}};
|
|
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { reconfigure_count => $reconfigure_count }});
|
|
|
|
if (not $reconfigure_count)
|
|
|
|
{
|
|
|
|
return(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
foreach my $wanted_interface (sort {$a cmp $b} keys %{$anvil->data->{network_manager}{reconfigure}})
|
|
|
|
{
|
|
|
|
my $uuid = $anvil->data->{network_manager}{reconfigure}{$wanted_interface}{from_uuid};
|
|
|
|
my $old_device = $anvil->data->{interface}{uuid}{$uuid}{device};
|
|
|
|
my $name = $anvil->data->{interface}{uuid}{$uuid}{'connection.id'};
|
|
|
|
my $mac_address = $anvil->data->{interface}{uuid}{$uuid}{mac_address};
|
|
|
|
my $type = $anvil->data->{interface}{uuid}{$uuid}{type};
|
|
|
|
print "Renaming old device/name: [".$old_device."/".$name."] with MAC: [".$mac_address."] to: [".$wanted_interface."] using UUID: [".$uuid."]\n";
|
|
|
|
|
|
|
|
# Read persistent-net and see if it needs to be updated.
|
|
|
|
my $new_persistent_net = "";
|
|
|
|
my $old_persistent_net = "";
|
|
|
|
if (-e $anvil->data->{path}{configs}{'persistent-net'})
|
|
|
|
{
|
|
|
|
$old_persistent_net = $anvil->Storage->read_file({debug => 2, file => $anvil->data->{path}{configs}{'persistent-net'}});
|
|
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { old_persistent_net => $old_persistent_net }});
|
|
|
|
}
|
|
|
|
foreach my $line (split/\n/, $old_persistent_net)
|
|
|
|
{
|
|
|
|
# If this MAC or device name exists already, delete the line.
|
|
|
|
if (($line =~ /"$mac_address"/) or ($line =~ /"$wanted_interface"/))
|
|
|
|
{
|
|
|
|
next;
|
|
|
|
}
|
|
|
|
$new_persistent_net .= $line."\n";
|
|
|
|
}
|
|
|
|
$new_persistent_net .= "SUBSYSTEM==\"net\",ACTION==\"add\",ATTR{address}==\"".$mac_address."\",ATTR{type}==\"".$type."\",NAME=\"".$wanted_interface."\"\n";
|
|
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { new_persistent_net => $new_persistent_net }});
|
|
|
|
|
|
|
|
my $difference = diff \$old_persistent_net, \$new_persistent_net, { STYLE => 'Unified' };
|
|
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { difference => $difference }});
|
|
|
|
|
|
|
|
# Write the new file.
|
|
|
|
if ($difference)
|
|
|
|
{
|
|
|
|
print "- Updating the udev file: [".$anvil->data->{path}{configs}{'persistent-net'}."]\n";
|
|
|
|
my $problem = $anvil->Storage->write_file({
|
|
|
|
file => $anvil->data->{path}{configs}{'persistent-net'},
|
|
|
|
body => $new_persistent_net,
|
|
|
|
overwrite => 1,
|
|
|
|
user => "admin",
|
|
|
|
group => "admin",
|
|
|
|
mode => "0644",
|
|
|
|
|
|
|
|
});
|
|
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { problem => $problem }});
|
|
|
|
if ($problem)
|
|
|
|
{
|
|
|
|
print "[ Error ] - Failed to write the new: [".$anvil->data->{path}{configs}{'persistent-net'}."] file, aborting!\n";
|
|
|
|
$anvil->nice_exit({exit_code => 1});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
# Update the connection.interface-name
|
|
|
|
my $connection_interface_name = $anvil->data->{interface}{uuid}{$uuid}{'connection.interface-name'} ? $anvil->data->{interface}{uuid}{$uuid}{'connection.interface-name'} : "";
|
|
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { connection_interface_name => $connection_interface_name }});
|
|
|
|
if ($connection_interface_name)
|
|
|
|
{
|
|
|
|
print "- Removing the old 'connection.interface-name': [".$connection_interface_name."]\n";
|
|
|
|
my $shell_call = $anvil->data->{path}{exe}{nmcli}." connection modify ".$uuid." connection.interface-name \"\"";
|
|
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { shell_call => $shell_call }});
|
|
|
|
my ($output, $return_code) = $anvil->System->call({shell_call => $shell_call});
|
|
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
|
|
output => $output,
|
|
|
|
return_code => $return_code,
|
|
|
|
}});
|
|
|
|
|
|
|
|
$shell_call = $anvil->data->{path}{exe}{nmcli}." --get-values connection.interface-name connection show ".$uuid;
|
|
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { shell_call => $shell_call }});
|
|
|
|
($output, $return_code) = $anvil->System->call({shell_call => $shell_call});
|
|
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
|
|
output => $output,
|
|
|
|
return_code => $return_code,
|
|
|
|
}});
|
|
|
|
|
|
|
|
if ($output)
|
|
|
|
{
|
|
|
|
# This should have been blank
|
|
|
|
print "[ Error ] - Failed to delete the 'connection.interface-name', got: [".$output."] and it should bhave been blank, aborting!\n";
|
|
|
|
$anvil->nice_exit({exit_code => 1});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
# We'll log what it was, and change it anyway
|
|
|
|
my $match_interface_name = $anvil->data->{interface}{uuid}{$uuid}{'match.interface-name'} ? $anvil->data->{interface}{uuid}{$uuid}{'match.interface-name'} : "";
|
|
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { match_interface_name => $match_interface_name }});
|
|
|
|
if (1)
|
|
|
|
{
|
|
|
|
print "- Matching the new interface name: [".$wanted_interface."] to the bios device name: [".$old_device."]\n";
|
|
|
|
my $shell_call = $anvil->data->{path}{exe}{nmcli}." connection modify ".$uuid." match.interface-name \"".$wanted_interface." ".$old_device."\"";
|
|
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { shell_call => $shell_call }});
|
|
|
|
my ($output, $return_code) = $anvil->System->call({shell_call => $shell_call});
|
|
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
|
|
output => $output,
|
|
|
|
return_code => $return_code,
|
|
|
|
}});
|
|
|
|
|
|
|
|
# Read it back
|
|
|
|
$shell_call = $anvil->data->{path}{exe}{nmcli}." --get-values match.interface-name connection show ".$uuid;
|
|
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { shell_call => $shell_call }});
|
|
|
|
($output, $return_code) = $anvil->System->call({shell_call => $shell_call});
|
|
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
|
|
output => $output,
|
|
|
|
return_code => $return_code,
|
|
|
|
}});
|
|
|
|
|
|
|
|
if (($output ne $wanted_interface.",".$old_device) && ($output ne $old_device.",".$wanted_interface))
|
|
|
|
{
|
|
|
|
# This should have been blank
|
|
|
|
print "[ Error ] - Failed to create the 'match.interface-name' value. Expected: [".$wanted_interface.",".$old_device."], got: [".$output."], aborting!\n";
|
|
|
|
$anvil->nice_exit({exit_code => 1});
|
|
|
|
}
|
|
|
|
|
|
|
|
# Set the connection.id to the old name.
|
|
|
|
print "- Setting the connection.id to the bios device name: [".$old_device."]\n";
|
|
|
|
$shell_call = $anvil->data->{path}{exe}{nmcli}." connection modify ".$uuid." connection.id \"".$old_device."\"";
|
|
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { shell_call => $shell_call }});
|
|
|
|
($output, $return_code) = $anvil->System->call({shell_call => $shell_call});
|
|
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
|
|
output => $output,
|
|
|
|
return_code => $return_code,
|
|
|
|
}});
|
|
|
|
|
|
|
|
# Read it back
|
|
|
|
$shell_call = $anvil->data->{path}{exe}{nmcli}." --get-values connection.id connection show ".$uuid;
|
|
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { shell_call => $shell_call }});
|
|
|
|
($output, $return_code) = $anvil->System->call({shell_call => $shell_call});
|
|
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
|
|
output => $output,
|
|
|
|
return_code => $return_code,
|
|
|
|
}});
|
|
|
|
}
|
|
|
|
|
|
|
|
# Set the reboot flag.
|
|
|
|
$anvil->data->{sys}{reboot_needed} = 1;
|
|
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "sys::reboot_needed" => $anvil->data->{sys}{reboot_needed} }});
|
|
|
|
}
|
|
|
|
|
|
|
|
if ($anvil->data->{sys}{reboot_needed})
|
|
|
|
{
|
|
|
|
print "Reboot needed.\n";
|
|
|
|
print "- Regenerating dracute initrd image, this can take a moment...\n";
|
|
|
|
my $shell_call = $anvil->data->{path}{exe}{dracut}." --force";
|
|
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { shell_call => $shell_call }});
|
|
|
|
my ($output, $return_code) = $anvil->System->call({shell_call => $shell_call});
|
|
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
|
|
output => $output,
|
|
|
|
return_code => $return_code,
|
|
|
|
}});
|
|
|
|
print "- New initrd image created, rebooting in 60 seconds (press 'ctrl + c' to abort).\n";
|
|
|
|
my $timeout = 60;
|
|
|
|
while($timeout)
|
|
|
|
{
|
|
|
|
if ($timeout % 10)
|
|
|
|
{
|
|
|
|
print "."
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
print $timeout;
|
|
|
|
}
|
|
|
|
sleep 1;
|
|
|
|
$timeout--;
|
|
|
|
}
|
|
|
|
print "0\n";
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
sub scan
|
|
|
|
{
|
|
|
|
my ($anvil) = @_;
|
|
|
|
|
|
|
|
# Get a list of interfaces.
|
|
|
|
get_interfaces($anvil);
|
|
|
|
|
|
|
|
return(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
sub get_interfaces
|
|
|
|
{
|
|
|
|
my ($anvil) = @_;
|
|
|
|
|
|
|
|
my $shell_call = $anvil->data->{path}{exe}{nmcli}." --get-values uuid,type,active,state connection show";
|
|
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { shell_call => $shell_call }});
|
|
|
|
my ($output, $return_code) = $anvil->System->call({shell_call => $shell_call});
|
|
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
|
|
output => $output,
|
|
|
|
return_code => $return_code,
|
|
|
|
}});
|
|
|
|
|
|
|
|
foreach my $line (split/\n/, $output)
|
|
|
|
{
|
|
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { line => $line }});
|
|
|
|
if ($line =~ /^(.*?):(.*?):(.*?):(.*?)$/)
|
|
|
|
{
|
|
|
|
my $uuid = $1;
|
|
|
|
my $type = $2;
|
|
|
|
my $active = $3;
|
|
|
|
my $state = $4;
|
|
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
|
|
uuid => $uuid,
|
|
|
|
type => $type,
|
|
|
|
active => $active,
|
|
|
|
'state' => $state,
|
|
|
|
}});
|
|
|
|
next if $type eq "loopback";
|
|
|
|
|
|
|
|
$anvil->data->{interface}{uuid}{$uuid}{type} = $type;
|
|
|
|
$anvil->data->{interface}{uuid}{$uuid}{active} = lc($active) eq "yes" ? 1 : 0;
|
|
|
|
$anvil->data->{interface}{uuid}{$uuid}{'state'} = lc($state);
|
|
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
|
|
"interface::uuid::${uuid}::type" => $anvil->data->{interface}{uuid}{$uuid}{type},
|
|
|
|
"interface::uuid::${uuid}::active" => $anvil->data->{interface}{uuid}{$uuid}{active},
|
|
|
|
"interface::uuid::${uuid}::state" => $anvil->data->{interface}{uuid}{$uuid}{'state'},
|
|
|
|
}});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
foreach my $uuid (sort {$a cmp $b} keys %{$anvil->data->{interface}{uuid}})
|
|
|
|
{
|
|
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { uuid => $uuid }});
|
|
|
|
|
|
|
|
# Collect all the rest of the data now.
|
|
|
|
my $shell_call = $anvil->data->{path}{exe}{nmcli}." connection show ".$uuid;
|
|
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { shell_call => $shell_call }});
|
|
|
|
|
|
|
|
my ($output, $return_code) = $anvil->System->call({shell_call => $shell_call});
|
|
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => {
|
|
|
|
output => $output,
|
|
|
|
return_code => $return_code,
|
|
|
|
}});
|
|
|
|
foreach my $line (split/\n/, $output)
|
|
|
|
{
|
|
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { line => $line }});
|
|
|
|
if ($line =~ /^(.*?):\s+(.*)$/)
|
|
|
|
{
|
|
|
|
my $variable = $1;
|
|
|
|
my $value = $2;
|
|
|
|
$anvil->data->{interface}{uuid}{$uuid}{$variable} = $value;
|
|
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
|
|
"interface::uuid::${uuid}::${variable}" => $anvil->data->{interface}{uuid}{$uuid}{$variable},
|
|
|
|
}});
|
|
|
|
|
|
|
|
if ($variable =~ /IP(\d).ADDRESS\[(\d+)\]/)
|
|
|
|
{
|
|
|
|
my $ip_type = $1;
|
|
|
|
my $sequence = $2;
|
|
|
|
my $hash_key = "ipv".$ip_type;
|
|
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
|
|
ip_type => $ip_type,
|
|
|
|
sequence => $sequence,
|
|
|
|
hash_key => $hash_key,
|
|
|
|
}});
|
|
|
|
|
|
|
|
if (($ip_type == 4) && ($value =~ /^(.*?)\/(.*)$/))
|
|
|
|
{
|
|
|
|
my $ip_address = $1;
|
|
|
|
my $subnet_mask = $2;
|
|
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
|
|
ip_address => $ip_address,
|
|
|
|
subnet_mask => $subnet_mask,
|
|
|
|
}});
|
|
|
|
|
|
|
|
$anvil->data->{interface}{uuid}{$uuid}{$hash_key}{ip}{$sequence}{ip_address} = $1;
|
|
|
|
$anvil->data->{interface}{uuid}{$uuid}{$hash_key}{ip}{$sequence}{subnet_mask} = $2;
|
|
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
|
|
"interface::uuid::${uuid}::${hash_key}::ip::${sequence}::ip_address" => $anvil->data->{interface}{uuid}{$uuid}{$hash_key}{ip}{$sequence}{ip_address},
|
|
|
|
"interface::uuid::${uuid}::${hash_key}::ip::${sequence}::subnet_mask" => $anvil->data->{interface}{uuid}{$uuid}{$hash_key}{ip}{$sequence}{subnet_mask},
|
|
|
|
}});
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
$anvil->data->{interface}{uuid}{$uuid}{$hash_key}{ip}{$sequence}{ip_address} = $value;
|
|
|
|
$anvil->data->{interface}{uuid}{$uuid}{$hash_key}{ip}{$sequence}{subnet_mask} = "";
|
|
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
|
|
"interface::uuid::${uuid}::${hash_key}::ip::${sequence}::ip_address" => $anvil->data->{interface}{uuid}{$uuid}{$hash_key}{ip}{$sequence}{ip_address},
|
|
|
|
"interface::uuid::${uuid}::${hash_key}::ip::${sequence}::subnet_mask" => $anvil->data->{interface}{uuid}{$uuid}{$hash_key}{ip}{$sequence}{subnet_mask},
|
|
|
|
}});
|
|
|
|
}
|
|
|
|
|
|
|
|
# Make sure the DNS key exists.
|
|
|
|
if (not exists $anvil->data->{interface}{uuid}{$uuid}{$hash_key}{dns})
|
|
|
|
{
|
|
|
|
$anvil->data->{interface}{uuid}{$uuid}{$hash_key}{dns} = "";
|
|
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
|
|
"interface::uuid::${uuid}::${hash_key}::dns" => $anvil->data->{interface}{uuid}{$uuid}{$sequence}{dns},
|
|
|
|
}});
|
|
|
|
}
|
|
|
|
if (not exists $anvil->data->{interface}{uuid}{$uuid}{$hash_key}{gateway})
|
|
|
|
{
|
|
|
|
$anvil->data->{interface}{uuid}{$uuid}{$hash_key}{gateway} = "";
|
|
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
|
|
"interface::uuid::${uuid}::${hash_key}::gateway" => $anvil->data->{interface}{uuid}{$uuid}{$sequence}{gateway},
|
|
|
|
}});
|
|
|
|
}
|
|
|
|
$anvil->data->{interface}{uuid}{$uuid}{$hash_key}{gateway} = $value;
|
|
|
|
}
|
|
|
|
if ($variable =~ /IP(\d).ROUTE\[(\d+)\]/)
|
|
|
|
{
|
|
|
|
my $ip_type = $1;
|
|
|
|
my $sequence = $2;
|
|
|
|
my $hash_key = "ipv".$ip_type;
|
|
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
|
|
ip_type => $ip_type,
|
|
|
|
sequence => $sequence,
|
|
|
|
hash_key => $hash_key,
|
|
|
|
}});
|
|
|
|
|
|
|
|
$anvil->data->{interface}{uuid}{$uuid}{$hash_key}{route}{$sequence} = $value;
|
|
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
|
|
"interface::uuid::${uuid}::${hash_key}::route::${sequence}" => $anvil->data->{interface}{uuid}{$uuid}{$hash_key}{route}{$sequence},
|
|
|
|
}});
|
|
|
|
}
|
|
|
|
if ($variable =~ /IP(\d).DNS\[(\d+)\]/)
|
|
|
|
{
|
|
|
|
my $ip_type = $1;
|
|
|
|
my $sequence = $2;
|
|
|
|
my $hash_key = "ipv".$ip_type;
|
|
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
|
|
ip_type => $ip_type,
|
|
|
|
sequence => $sequence,
|
|
|
|
hash_key => $hash_key,
|
|
|
|
}});
|
|
|
|
|
|
|
|
if ((exists $anvil->data->{interface}{uuid}{$uuid}{$hash_key}{dns}) and ($anvil->data->{interface}{uuid}{$uuid}{$hash_key}{dns} ne ""))
|
|
|
|
{
|
|
|
|
$anvil->data->{interface}{uuid}{$uuid}{$hash_key}{dns} .= ",".$value;
|
|
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
|
|
"interface::uuid::${uuid}::${hash_key}::dns" => $anvil->data->{interface}{uuid}{$uuid}{$sequence}{dns},
|
|
|
|
}});
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
$anvil->data->{interface}{uuid}{$uuid}{$hash_key}{dns} = $value;
|
|
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
|
|
"interface::uuid::${uuid}::${hash_key}::dns" => $anvil->data->{interface}{uuid}{$uuid}{$hash_key}{dns},
|
|
|
|
}});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if ($variable =~ /IP(\d).GATEWAY/)
|
|
|
|
{
|
|
|
|
my $ip_type = $1;
|
|
|
|
my $hash_key = "ipv".$ip_type;
|
|
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
|
|
ip_type => $ip_type,
|
|
|
|
hash_key => $hash_key,
|
|
|
|
}});
|
|
|
|
|
|
|
|
$anvil->data->{interface}{uuid}{$uuid}{$hash_key}{gateway} = $value;
|
|
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
|
|
"interface::uuid::${uuid}::${hash_key}::gateway" => $anvil->data->{interface}{uuid}{$uuid}{$hash_key}{gateway},
|
|
|
|
}});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
# Now loop through and look for the name that maps to what's shown in 'ip addr list'. This can be a bit tricky.
|
|
|
|
foreach my $uuid (sort {$a cmp $b} keys %{$anvil->data->{interface}{uuid}})
|
|
|
|
{
|
|
|
|
my $connection_interface_name = $anvil->data->{interface}{uuid}{$uuid}{'connection.interface-name'} // "";
|
|
|
|
my $general_devices = $anvil->data->{interface}{uuid}{$uuid}{'GENERAL.DEVICES'} // "";
|
|
|
|
my $device = $connection_interface_name ne "--" ? $connection_interface_name : $general_devices;
|
|
|
|
my $name =
|
|
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
|
|
's1:uuid' => $uuid,
|
|
|
|
's2:connection_interface_name' => $connection_interface_name,
|
|
|
|
's3:general_devices' => $general_devices,
|
|
|
|
's4:device' => $device,
|
|
|
|
}});
|
|
|
|
|
|
|
|
if ($device)
|
|
|
|
{
|
|
|
|
$anvil->data->{interface}{device}{$device}{uuid} = $uuid;
|
|
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
|
|
"interface::device::${device}::uuid" => $anvil->data->{interface}{device}{$device}{uuid},
|
|
|
|
}});
|
|
|
|
|
|
|
|
### Get some data from sysfs.
|
|
|
|
$anvil->data->{interface}{uuid}{$uuid}{device} = $device;
|
|
|
|
$anvil->data->{interface}{uuid}{$uuid}{mac_address} = "";
|
|
|
|
$anvil->data->{interface}{uuid}{$uuid}{type} = "";
|
|
|
|
$anvil->data->{interface}{uuid}{$uuid}{mtu} = 0;
|
|
|
|
|
|
|
|
# The 'connection.timestamp' seems to be where the 'connected' (as in, have an IP)
|
|
|
|
# comes from.
|
|
|
|
$anvil->data->{interface}{uuid}{$uuid}{connected} = $anvil->data->{interface}{uuid}{$uuid}{'connection.timestamp'} ? $anvil->data->{interface}{uuid}{$uuid}{'connection.timestamp'} : 0;
|
|
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
|
|
"interface::uuid::${uuid}::connected" => $anvil->data->{interface}{uuid}{$uuid}{connected},
|
|
|
|
}});
|
|
|
|
|
|
|
|
# MAC address
|
|
|
|
my $mac_address_file = "/sys/class/net/".$device."/address";
|
|
|
|
my $type_file = "/sys/class/net/".$device."/type";
|
|
|
|
my $mtu_file = "/sys/class/net/".$device."/mtu";
|
|
|
|
if (-e $mac_address_file)
|
|
|
|
{
|
|
|
|
my $mac_address = $anvil->Storage->read_file({file => $mac_address_file});
|
|
|
|
$mac_address =~ s/\n$//;
|
|
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { mac_address => $mac_address }});
|
|
|
|
|
|
|
|
if (($mac_address) && ($mac_address ne "!!error!!"))
|
|
|
|
{
|
|
|
|
$anvil->data->{interface}{uuid}{$uuid}{mac_address} = $mac_address;
|
|
|
|
$anvil->data->{interface}{mac_address}{$mac_address}{uuid} = $uuid;
|
|
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
|
|
"interface::uuid::${uuid}::mac_address" => $anvil->data->{interface}{uuid}{$uuid}{mac_address},
|
|
|
|
"interface::mac_address::${mac_address}::uuid" => $anvil->data->{interface}{mac_address}{$mac_address}{uuid},
|
|
|
|
}});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (-e $type_file)
|
|
|
|
{
|
|
|
|
my $type = $anvil->Storage->read_file({file => $type_file});
|
|
|
|
$type =~ s/\n$//;
|
|
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { type => $type }});
|
|
|
|
|
|
|
|
if (($type) && ($type ne "!!error!!"))
|
|
|
|
{
|
|
|
|
$anvil->data->{interface}{uuid}{$uuid}{type} = $type;
|
|
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
|
|
"interface::uuid::${uuid}::type" => $anvil->data->{interface}{uuid}{$uuid}{type},
|
|
|
|
}});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (-e $mtu_file)
|
|
|
|
{
|
|
|
|
my $mtu = $anvil->Storage->read_file({file => $mtu_file});
|
|
|
|
$mtu =~ s/\n$//;
|
|
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { mtu => $mtu }});
|
|
|
|
|
|
|
|
if (($mtu) && ($mtu ne "!!error!!"))
|
|
|
|
{
|
|
|
|
$anvil->data->{interface}{uuid}{$uuid}{mtu} = $mtu;
|
|
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
|
|
"interface::uuid::${uuid}::mtu" => $anvil->data->{interface}{uuid}{$uuid}{mtu},
|
|
|
|
}});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
# Now lets confirm we got all the interfaces, including the down'ed ones.
|
|
|
|
foreach my $device (sort {$a cmp $b} keys %{$anvil->data->{interface}{device}})
|
|
|
|
{
|
|
|
|
my $uuid = $anvil->data->{interface}{device}{$device}{uuid};
|
|
|
|
my $name = $anvil->data->{interface}{uuid}{$uuid}{'connection.id'};
|
|
|
|
my $mac_address = $anvil->data->{interface}{uuid}{$uuid}{mac_address};
|
|
|
|
my $type = $anvil->data->{interface}{uuid}{$uuid}{type};
|
|
|
|
my $mtu_type = $anvil->data->{interface}{uuid}{$uuid}{'802-3-ethernet.mtu'};
|
|
|
|
my $mtu = $anvil->data->{interface}{uuid}{$uuid}{mtu};
|
|
|
|
my $active = $anvil->data->{interface}{uuid}{$uuid}{active};
|
|
|
|
my $state = $anvil->data->{interface}{uuid}{$uuid}{'state'};
|
|
|
|
my $connected = $anvil->data->{interface}{uuid}{$uuid}{connected};
|
|
|
|
my $ipv4_dns = $anvil->data->{interface}{uuid}{$uuid}{ipv4}{dns} // "--";
|
|
|
|
my $ipv4_gateway = $anvil->data->{interface}{uuid}{$uuid}{ipv4}{gateway} // "--";
|
|
|
|
my $ip_count = keys %{$anvil->data->{interface}{uuid}{$uuid}{ipv4}{ip}};
|
|
|
|
my $route_count = keys %{$anvil->data->{interface}{uuid}{$uuid}{ipv4}{route}};
|
|
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
|
|
"s01:device" => $device,
|
|
|
|
"s02:uuid" => $uuid,
|
|
|
|
"s03:name" => $name,
|
|
|
|
"s04:mac_address" => $mac_address,
|
|
|
|
"s05:type" => $type,
|
|
|
|
"s06:mtu_type" => $mtu_type,
|
|
|
|
"s07:active" => $active,
|
|
|
|
"s08:state" => $state,
|
|
|
|
"s09:connected" => $connected,
|
|
|
|
"s10:ipv4_dns" => $ipv4_dns,
|
|
|
|
"s11:ipv4_gateway" => $ipv4_gateway,
|
|
|
|
"s12:ip_count" => $ip_count,
|
|
|
|
"s13:route_count" => $route_count,
|
|
|
|
}});
|
|
|
|
|
|
|
|
#print "- Device: [".$device."], Name: [".$name."], MAC: [".$mac_address."], UUID: [".$uuid."]\n";
|
|
|
|
# $anvil->data->{network_manager}{want}{ifn1_link1}{mac_address} = "52:54:00:d3:19:cc";
|
|
|
|
# $anvil->data->{network_manager}{want}{ifn1_link1}{device} = "enp1s0";
|
|
|
|
# $anvil->data->{network_manager}{want}{ifn1_link1}{found} = 0;
|
|
|
|
if (exists $anvil->data->{network_manager}{want}{$device})
|
|
|
|
{
|
|
|
|
# We know this device. Does it match the expected MAC address?
|
|
|
|
my $wanted_mac_address = $anvil->data->{network_manager}{want}{ifn1_link1}{mac_address};
|
|
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { wanted_mac_address => $wanted_mac_address }});
|
|
|
|
if (lc($wanted_mac_address) eq lc($mac_address))
|
|
|
|
{
|
|
|
|
#print " - Interface is configured as desired.\n";
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
#print " - The MAC address doesn't match the desired MAC address!\n";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
#print " - This interface isn't one of the matched ones. Check if this should be reconfigured.\n";
|
|
|
|
my $reconfigure_to = "";
|
|
|
|
foreach my $wanted_interface (sort {$a cmp $b} keys %{$anvil->data->{network_manager}{want}})
|
|
|
|
{
|
|
|
|
my $wanted_device = $anvil->data->{network_manager}{want}{$wanted_interface}{device};
|
|
|
|
my $wanted_mac_address = $anvil->data->{network_manager}{want}{$wanted_interface}{mac_address};
|
|
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
|
|
wanted_interface => $wanted_interface,
|
|
|
|
wanted_device => $wanted_device,
|
|
|
|
wanted_mac_address => $wanted_mac_address,
|
|
|
|
}});
|
|
|
|
|
|
|
|
# If this device already exists, skip it.
|
|
|
|
if (exists $anvil->data->{interface}{device}{$wanted_interface})
|
|
|
|
{
|
|
|
|
next;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ($mac_address eq $wanted_mac_address)
|
|
|
|
{
|
|
|
|
# MAC address always takes priority.
|
|
|
|
$reconfigure_to = $wanted_interface;
|
|
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { reconfigure_to => $reconfigure_to }});
|
|
|
|
next;
|
|
|
|
}
|
|
|
|
elsif ((not $reconfigure_to) && ($wanted_device eq $name))
|
|
|
|
{
|
|
|
|
$reconfigure_to = $wanted_interface;
|
|
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { reconfigure_to => $reconfigure_to }});
|
|
|
|
next;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if ($reconfigure_to)
|
|
|
|
{
|
|
|
|
# Reconfigure!
|
|
|
|
#print " - This should be: [".$reconfigure_to."]\n";
|
|
|
|
$anvil->data->{network_manager}{reconfigure}{$reconfigure_to}{from_uuid} = $uuid;
|
|
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
|
|
"network_manager::reconfigure::${reconfigure_to}::from_uuid" => $anvil->data->{network_manager}{reconfigure}{$reconfigure_to}{from_uuid},
|
|
|
|
}});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#print "- Device: [".$device."], UUID: [".$uuid."], name: [".$name."], state: [".$active."], active?: [".$active."], state: [".$state."], connected: [".$connected."]\n";
|
|
|
|
#print " - MAC: [".$mac_address."], Type: [".$type."], MTU: [".$mtu."] MTU type: [".$mtu_type."], IPv4 DNS: [".$ipv4_dns."], Gateway: [".$ipv4_gateway."], IPs: [".$ip_count."], routes: [".$route_count."]\n";
|
|
|
|
if ($ip_count)
|
|
|
|
{
|
|
|
|
foreach my $sequence (sort {$a <=> $b} keys %{$anvil->data->{interface}{uuid}{$uuid}{ipv4}{ip}})
|
|
|
|
{
|
|
|
|
my $ip_address = $anvil->data->{interface}{uuid}{$uuid}{ipv4}{ip}{$sequence}{ip_address};
|
|
|
|
my $subnet_mask = $anvil->data->{interface}{uuid}{$uuid}{ipv4}{ip}{$sequence}{subnet_mask};
|
|
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
|
|
"s1:sequence" => $sequence,
|
|
|
|
"s2:ip_address" => $ip_address,
|
|
|
|
"s3:subnet_mask" => $subnet_mask,
|
|
|
|
}});
|
|
|
|
#print " - ".$sequence.": IPv4 IP: [".$ip_address."], subnet mask: [".$subnet_mask."]\n";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if ($route_count)
|
|
|
|
{
|
|
|
|
foreach my $sequence (sort {$a <=> $b} keys %{$anvil->data->{interface}{uuid}{$uuid}{ipv4}{route}})
|
|
|
|
{
|
|
|
|
my $route = $anvil->data->{interface}{uuid}{$uuid}{ipv4}{route}{$sequence};
|
|
|
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
|
|
|
"s1:sequence" => $sequence,
|
|
|
|
"s2:route" => $route,
|
|
|
|
}});
|
|
|
|
#print " - ".$sequence.": Route: [".$route."]\n";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#print "--------\n";
|
|
|
|
}
|
|
|
|
|
|
|
|
return(0);
|
|
|
|
}
|