* Updated System->get_ips() to determine which interface is the default gateway and set the gateway IP and active DNS servers.

* Created (but not yet tested) Database->insert_or_update_ip_addresses() and the associated ip_addresses database table to store IP address details and reference the interface they're on.

Signed-off-by: Digimer <digimer@alteeve.ca>
main
Digimer 7 years ago
parent 4e6f492c4f
commit a6e50f15a9
  1. 302
      Anvil/Tools/Database.pm
  2. 101
      Anvil/Tools/System.pm
  3. 82
      tools/anvil-update-states
  4. 70
      tools/anvil.sql

@ -23,6 +23,7 @@ my $THIS_FILE = "Database.pm";
# get_local_uuid # get_local_uuid
# initialize # initialize
# insert_or_update_hosts # insert_or_update_hosts
# insert_or_update_ip_addresses
# insert_or_update_jobs # insert_or_update_jobs
# insert_or_update_network_interfaces # insert_or_update_network_interfaces
# insert_or_update_states # insert_or_update_states
@ -1387,7 +1388,7 @@ sub initialize
=head2 insert_or_update_hosts =head2 insert_or_update_hosts
This updates (or inserts) a record in the 'hosts' table. This updates (or inserts) a record in the 'hosts' table. The C<< host_uuid >> UUID will be returned.
If there is an error, an empty string is returned. If there is an error, an empty string is returned.
@ -1524,7 +1525,304 @@ WHERE
} }
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => $debug, key => "log_0126", variables => { method => "Database->insert_or_update_hosts()" }}); $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => $debug, key => "log_0126", variables => { method => "Database->insert_or_update_hosts()" }});
return(0); return($host_uuid);
}
=head2 insert_or_update_ip_addresses
This updates (or inserts) a record in the 'ip_addresses' table. The C<< ip_address_uuid >> referencing the database row will be returned.
If there is an error, an empty string is returned.
Parameters;
=head3 uuid (optional)
If set, only the corresponding database will be written to.
=head3 file (optional)
If set, this is the file name logged as the source of any INSERTs or UPDATEs.
=head3 line (optional)
If set, this is the file line number logged as the source of any INSERTs or UPDATEs.
=head2 ip_address_uuid (optional)
If not passed, a check will be made to see if an existing entry is found for C<< ip_address_address >>. If found, that entry will be updated. If not found, a new record will be inserted.
=head2 ip_address_host_uuid (optional)
This is the host that the IP address is on. If not passed, the local C<< sys::host_uuid >> will be used (indicating it is a local IP address).
=head2 ip_address_on_type (required)
This indicates what type of interface the IP address is on. This must be either C<< interface >>, C<< bond >> or C<< bridge >>.
=head2 ip_address_on_uuid (required)
This is the UUID of the bridge, bond or interface that this IP address is on.
=head2 ip_address_address (required)
This is the acual IP address. It's tested with IPv4 addresses in dotted-decimal format, though it can also store IPv6 addresses. If this is set to C<< 0 >>, it will be treated as deleted and will be ignored (unless a new IP is assigned to the same interface in the future).
=head2 ip_address_subnet (required)
This is the subnet mask for the IP address. It is tested with IPv4 in dotted decimal format, though it can also store IPv6 format subnet masks.
=head2 ip_address_default_gateway (optional, default '0')
If a gateway address is set, and this is set to C<< 1 >>, the associated interface will be the default gateway for the host.
=head2 ip_address_gateway (optional)
This is an option gateway IP address for this interface.
=head2 ip_address_dns (optional)
This is a comma-separated list of DNS servers used to resolve host names. This is recorded, but ignored unless C<< ip_address_gateway >> is set. Example format is C<< 8.8.8.8 >> or C<< 8.8.8.8,4.4.4.4 >>.
=cut
sub insert_or_update_ip_addresses
{
my $self = shift;
my $parameter = shift;
my $anvil = $self->parent;
my $debug = defined $parameter->{debug} ? $parameter->{debug} : 3;
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => $debug, key => "log_0125", variables => { method => "Database->insert_or_update_ip_addresses()" }});
my $uuid = defined $parameter->{uuid} ? $parameter->{uuid} : "";
my $file = defined $parameter->{file} ? $parameter->{file} : "";
my $line = defined $parameter->{line} ? $parameter->{line} : "";
my $ip_address_uuid = defined $parameter->{ip_address_uuid} ? $parameter->{ip_address_uuid} : "";
my $ip_address_host_uuid = defined $parameter->{ip_address_host_uuid} ? $parameter->{ip_address_host_uuid} : $anvil->data->{sys}{host_uuid};
my $ip_address_on_type = defined $parameter->{ip_address_on_type} ? $parameter->{ip_address_on_type} : "";
my $ip_address_on_uuid = defined $parameter->{ip_address_on_uuid} ? $parameter->{ip_address_on_uuid} : "";
my $ip_address_address = defined $parameter->{ip_address_address} ? $parameter->{ip_address_address} : "";
my $ip_address_subnet = defined $parameter->{ip_address_subnet} ? $parameter->{ip_address_subnet} : "";
my $ip_address_gateway = defined $parameter->{ip_address_gateway} ? $parameter->{ip_address_gateway} : "NULL";
my $ip_address_default_gateway = defined $parameter->{ip_address_default_gateway} ? $parameter->{ip_address_default_gateway} : 0;
my $ip_address_dns = defined $parameter->{ip_address_dns} ? $parameter->{ip_address_dns} : "NULL";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
uuid => $uuid,
file => $file,
line => $line,
ip_address_uuid => $ip_address_uuid,
ip_address_host_uuid => $ip_address_host_uuid,
ip_address_on_type => $ip_address_on_type,
ip_address_on_uuid => $ip_address_on_uuid,
ip_address_address => $ip_address_address,
ip_address_subnet => $ip_address_subnet,
ip_address_gateway => $ip_address_gateway,
ip_address_default_gateway => $ip_address_default_gateway,
ip_address_dns => $ip_address_dns,
}});
if (not $ip_address_on_type)
{
# Throw an error and exit.
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "err", key => "log_0020", variables => { method => "Database->insert_or_update_ip_addresses()", parameter => "ip_address_on_type" }});
return("");
}
if (not $ip_address_on_uuid)
{
# Throw an error and exit.
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "err", key => "log_0020", variables => { method => "Database->insert_or_update_ip_addresses()", parameter => "ip_address_on_uuid" }});
return("");
}
if (not $ip_address_address)
{
# Throw an error and exit.
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "err", key => "log_0020", variables => { method => "Database->insert_or_update_ip_addresses()", parameter => "ip_address_address" }});
return("");
}
if (not $ip_address_subnet)
{
# Throw an error and exit.
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "err", key => "log_0020", variables => { method => "Database->insert_or_update_ip_addresses()", parameter => "ip_address_subnet" }});
return("");
}
# If we don't have a UUID, see if we can find one for the given ip_address server name.
if (not $ip_address_uuid)
{
my $query = "
SELECT
ip_address_uuid
FROM
ip_addresses
WHERE
ip_address_address = ".$anvil->data->{sys}{use_db_fh}->quote($ip_address_address)."
AND
ip_address_host_uuid = ".$anvil->data->{sys}{use_db_fh}->quote($ip_address_host_uuid)."
;";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { query => $query }});
my $results = $anvil->Database->query({query => $query, source => $file ? $file : $THIS_FILE, line => $line ? $line : __LINE__});
my $count = @{$results};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
results => $results,
count => $count,
}});
if ($count)
{
$ip_address_uuid = $results->[0]->[0];
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { ip_address_uuid => $ip_address_uuid }});
}
}
# default gateway is a boolean, so translate it.
my $say_ip_address_default_gateway = (($ip_address_default_gateway eq "1") or ($ip_address_default_gateway =~ /true/i)) ? "TRUE" : "FALSE";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { say_ip_address_default_gateway => $say_ip_address_default_gateway }});
# If I still don't have an ip_address_uuid, we're INSERT'ing .
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { ip_address_uuid => $ip_address_uuid }});
if (not $ip_address_uuid)
{
# It's possible that this is called before the host is recorded in the database. So to be
# safe, we'll return without doing anything if there is no host_uuid in the database.
my $hosts = $anvil->Database->get_hosts();
my $found = 0;
foreach my $hash_ref (@{$hosts})
{
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
"hash_ref->{host_uuid}" => $hash_ref->{host_uuid},
"sys::host_uuid" => $anvil->data->{sys}{host_uuid},
}});
if ($hash_ref->{host_uuid} eq $anvil->data->{sys}{host_uuid})
{
$found = 1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { found => $found }});
}
}
if (not $found)
{
# We're out.
return("");
}
# INSERT
$ip_address_uuid = $anvil->Get->uuid();
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { ip_address_uuid => $ip_address_uuid }});
my $query = "
INSERT INTO
ip_addresses
(
ip_address_uuid,
ip_address_host_uuid,
ip_address_on_type,
ip_address_on_uuid,
ip_address_address,
ip_address_subnet,
ip_address_gateway,
ip_address_default_gateway,
ip_address_dns,
modified_date
) VALUES (
".$anvil->data->{sys}{use_db_fh}->quote($ip_address_uuid).",
".$anvil->data->{sys}{use_db_fh}->quote($ip_address_host_uuid).",
".$anvil->data->{sys}{use_db_fh}->quote($ip_address_on_type).",
".$anvil->data->{sys}{use_db_fh}->quote($ip_address_on_uuid).",
".$anvil->data->{sys}{use_db_fh}->quote($ip_address_address).",
".$anvil->data->{sys}{use_db_fh}->quote($ip_address_subnet).",
".$anvil->data->{sys}{use_db_fh}->quote($ip_address_gateway).",
$say_ip_address_default_gateway,
".$anvil->data->{sys}{use_db_fh}->quote($ip_address_dns).",
".$anvil->data->{sys}{use_db_fh}->quote($anvil->data->{sys}{db_timestamp})."
);
";
$query =~ s/'NULL'/NULL/g;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { query => $query }});
$anvil->Database->write({query => $query, source => $file ? $file : $THIS_FILE, line => $line ? $line : __LINE__});
}
else
{
# Query the rest of the values and see if anything changed.
my $query = "
SELECT
ip_address_host_uuid,
ip_address_on_type,
ip_address_on_uuid,
ip_address_address,
ip_address_subnet,
ip_address_gateway,
ip_address_default_gateway,
ip_address_dns
FROM
ip_addresses
WHERE
ip_address_uuid = ".$anvil->data->{sys}{use_db_fh}->quote($ip_address_uuid)."
;";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { query => $query }});
my $results = $anvil->Database->query({query => $query, source => $file ? $file : $THIS_FILE, line => $line ? $line : __LINE__});
my $count = @{$results};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
results => $results,
count => $count,
}});
foreach my $row (@{$results})
{
my $old_ip_address_host_uuid = $row->[0];
my $old_ip_address_on_type = $row->[1];
my $old_ip_address_on_uuid = $row->[2];
my $old_ip_address_address = $row->[3];
my $old_ip_address_subnet = $row->[4];
my $old_ip_address_gateway = defined $row->[5] ? $row->[5] : "NULL";
my $old_ip_address_default_gateway = $row->[6];
my $old_ip_address_dns = defined $row->[7] ? $row->[7] : "NULL";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
old_ip_address_host_uuid => $old_ip_address_host_uuid,
old_ip_address_on_type => $old_ip_address_on_type,
old_ip_address_on_uuid => $old_ip_address_on_uuid,
old_ip_address_address => $old_ip_address_address,
old_ip_address_subnet => $old_ip_address_subnet,
old_ip_address_gateway => $old_ip_address_gateway,
old_ip_address_default_gateway => $old_ip_address_default_gateway,
old_ip_address_dns => $old_ip_address_dns,
}});
my $say_old_ip_address_default_gateway = (($old_ip_address_default_gateway eq "1") or ($old_ip_address_default_gateway =~ /true/i)) ? "TRUE" : "FALSE";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { say_old_ip_address_default_gateway => $say_old_ip_address_default_gateway }});
# Anything change?
if (($old_ip_address_host_uuid ne $ip_address_host_uuid) or
($old_ip_address_on_type ne $ip_address_on_type) or
($old_ip_address_on_uuid ne $ip_address_on_uuid) or
($old_ip_address_address ne $ip_address_address) or
($old_ip_address_subnet ne $ip_address_subnet) or
($old_ip_address_gateway ne $ip_address_gateway) or
($say_old_ip_address_default_gateway ne $say_ip_address_default_gateway) or
($old_ip_address_dns ne $ip_address_dns))
{
# Something changed, save.
my $query = "
UPDATE
ip_addresses
SET
ip_address_host_uuid = ".$anvil->data->{sys}{use_db_fh}->quote($ip_address_host_uuid).",
ip_address_on_type = ".$anvil->data->{sys}{use_db_fh}->quote($ip_address_on_type).",
ip_address_on_uuid = ".$anvil->data->{sys}{use_db_fh}->quote($ip_address_on_uuid).",
ip_address_address = ".$anvil->data->{sys}{use_db_fh}->quote($ip_address_address).",
ip_address_subnet = ".$anvil->data->{sys}{use_db_fh}->quote($ip_address_subnet).",
ip_address_gateway = ".$anvil->data->{sys}{use_db_fh}->quote($ip_address_gateway).",
ip_address_default_gateway = $say_ip_address_default_gateway,
ip_address_dns = ".$anvil->data->{sys}{use_db_fh}->quote($ip_address_dns).",
modified_date = ".$anvil->data->{sys}{use_db_fh}->quote($anvil->data->{sys}{db_timestamp})."
WHERE
ip_address_uuid = ".$anvil->data->{sys}{use_db_fh}->quote($ip_address_uuid)."
";
$query =~ s/'NULL'/NULL/g;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { query => $query }});
$anvil->Database->write({query => $query, source => $file ? $file : $THIS_FILE, line => $line ? $line : __LINE__});
}
}
}
return($ip_address_uuid);
} }

@ -511,9 +511,12 @@ sub enable_daemon
This method checks the local system for interfaces and stores them in: This method checks the local system for interfaces and stores them in:
* C<< sys::network::interface::<iface_name>::ip >> - If an IP address is set * C<< sys::network::interface::<iface_name>::ip >> - If an IP address is set
* C<< sys::network::interface::<iface_name>::subnet >> - If an IP is set * C<< sys::network::interface::<iface_name>::subnet >> - If an IP is set
* C<< sys::network::interface::<iface_name>::mac >> - Always set. * C<< sys::network::interface::<iface_name>::mac >> - Always set.
* C<< sys::network::interface::<iface_name>::default_gateway >> = C<< 0 >> if not the default gateway, C<< 1 >> if so.
* C<< sys::network::interface::<iface_name>::gateway >> = If the default gateway, this is the gateway IP address.
* C<< sys::network::interface::<iface_name>::dns >> = If the default gateway, this is the comma-separated list of active DNS servers.
To aid in look-up by MAC address, C<< sys::mac::<mac_address>::iface >> is also set. To aid in look-up by MAC address, C<< sys::mac::<mac_address>::iface >> is also set.
@ -527,7 +530,7 @@ sub get_ips
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => $debug, key => "log_0125", variables => { method => "System->get_ips()" }}); $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => $debug, key => "log_0125", variables => { method => "System->get_ips()" }});
my $in_iface = ""; my $in_iface = "";
my $ip_addr = $anvil->System->call({shell_call => $anvil->data->{path}{exe}{ip}." addr list"}); my $ip_addr = $anvil->System->call({debug => $debug, shell_call => $anvil->data->{path}{exe}{ip}." addr list"});
foreach my $line (split/\n/, $ip_addr) foreach my $line (split/\n/, $ip_addr)
{ {
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { line => $line }}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { line => $line }});
@ -536,9 +539,12 @@ sub get_ips
$in_iface = $1; $in_iface = $1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { in_iface => $in_iface }}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { in_iface => $in_iface }});
$anvil->data->{sys}{network}{interface}{$in_iface}{ip} = "" if not defined $anvil->data->{sys}{network}{interface}{$in_iface}{ip}; $anvil->data->{sys}{network}{interface}{$in_iface}{ip} = "" if not defined $anvil->data->{sys}{network}{interface}{$in_iface}{ip};
$anvil->data->{sys}{network}{interface}{$in_iface}{subnet} = "" if not defined $anvil->data->{sys}{network}{interface}{$in_iface}{subnet}; $anvil->data->{sys}{network}{interface}{$in_iface}{subnet} = "" if not defined $anvil->data->{sys}{network}{interface}{$in_iface}{subnet};
$anvil->data->{sys}{network}{interface}{$in_iface}{mac} = "" if not defined $anvil->data->{sys}{network}{interface}{$in_iface}{mac}; $anvil->data->{sys}{network}{interface}{$in_iface}{mac} = "" if not defined $anvil->data->{sys}{network}{interface}{$in_iface}{mac};
$anvil->data->{sys}{network}{interface}{$in_iface}{default_gateway} = 0 if not defined $anvil->data->{sys}{network}{interface}{$in_iface}{default_gateway};
$anvil->data->{sys}{network}{interface}{$in_iface}{gateway} = "" if not defined $anvil->data->{sys}{network}{interface}{$in_iface}{gateway};
$anvil->data->{sys}{network}{interface}{$in_iface}{dns} = "" if not defined $anvil->data->{sys}{network}{interface}{$in_iface}{dns};
} }
next if not $in_iface; next if not $in_iface;
next if $in_iface eq "lo"; next if $in_iface eq "lo";
@ -565,9 +571,9 @@ sub get_ips
} }
if ($line =~ /ether ([0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}) /i) if ($line =~ /ether ([0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}) /i)
{ {
my $mac = $1; my $mac = $1;
$anvil->data->{sys}{network}{interface}{$in_iface}{mac} = $mac; $anvil->data->{sys}{network}{interface}{$in_iface}{mac} = $mac;
$anvil->data->{sys}{mac}{$mac}{iface} = $in_iface; $anvil->data->{sys}{mac}{$mac}{iface} = $in_iface;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
"sys::network::interface::${in_iface}::mac" => $anvil->data->{sys}{network}{interface}{$in_iface}{mac}, "sys::network::interface::${in_iface}::mac" => $anvil->data->{sys}{network}{interface}{$in_iface}{mac},
"sys::mac::${mac}::iface" => $anvil->data->{sys}{mac}{$mac}{iface}, "sys::mac::${mac}::iface" => $anvil->data->{sys}{mac}{$mac}{iface},
@ -575,6 +581,83 @@ sub get_ips
} }
} }
# Get the routing info.
my $lowest_metric = 99999999;
my $route_interface = "";
my $route_ip = "";
my $ip_route = $anvil->System->call({debug => $debug, shell_call => $anvil->data->{path}{exe}{ip}." route show"});
foreach my $line (split/\n/, $ip_route)
{
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { line => $line }});
if ($line =~ /default via (.*?) dev (.*?) proto static metric (\d+)/i)
{
my $this_ip = $1;
my $this_interface = $2;
my $metric = $3;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
this_ip => $this_ip,
this_interface => $this_interface,
metric => $metric,
}});
if ($metric < $lowest_metric)
{
$lowest_metric = $metric;
$route_interface = $this_interface;
$route_ip = $this_ip;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
lowest_metric => $lowest_metric,
route_interface => $route_interface,
route_ip => $route_ip,
}});
}
}
}
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
route_interface => $route_interface,
route_ip => $route_ip,
}});
# If I got a route, get the DNS.
if ($route_interface)
{
my $dns_list = "";
my $dns_hash = {};
my $ip_route = $anvil->System->call({debug => $debug, shell_call => $anvil->data->{path}{exe}{nmcli}." dev show"});
foreach my $line (split/\n/, $ip_route)
{
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { line => $line }});
if ($line =~ /IP4.DNS\[(\d+)\]:\s+(.*)/i)
{
my $order = $1;
my $ip = $2;
$dns_hash->{$order} = $ip;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { "dns_hash->{$order}" => $dns_hash->{$order} }});
}
}
foreach my $order (sort {$a cmp $b} keys %{$dns_hash})
{
$dns_list .= $dns_hash->{$order}.",";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
"s1:dns_hash->{$order}" => $dns_hash->{$order},
"s2:dns_list" => $dns_list,
}});
}
$dns_list =~ s/,$//;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { dns_list => $dns_list }});
$anvil->data->{sys}{network}{interface}{$route_interface}{default_gateway} = 1;
$anvil->data->{sys}{network}{interface}{$route_interface}{gateway} = $route_ip;
$anvil->data->{sys}{network}{interface}{$route_interface}{dns} = $dns_list;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
"sys::network::interface::${route_interface}::default_gateway" => $anvil->data->{sys}{network}{interface}{$route_interface}{default_gateway},
"sys::network::interface::${route_interface}::gateway" => $anvil->data->{sys}{network}{interface}{$route_interface}{gateway},
"sys::network::interface::${route_interface}::dns" => $anvil->data->{sys}{network}{interface}{$route_interface}{dns},
}});
}
return(0); return(0);
} }

@ -81,8 +81,7 @@ sub report_network
my $subnet_mask = ""; my $subnet_mask = "";
my $speed = $link_state ? $anvil->Storage->read_file({file => $full_path."/speed", debug => 2}) : 0; # Mbps (ie: 1000 = Gbps), gives a very high number for unplugged link my $speed = $link_state ? $anvil->Storage->read_file({file => $full_path."/speed", debug => 2}) : 0; # Mbps (ie: 1000 = Gbps), gives a very high number for unplugged link
my $media = "unknown"; my $media = "unknown";
my $is_bond = 0; my $type = "interface";
my $is_slave = 0;
if (exists $anvil->data->{sys}{network}{interface}{$interface}) if (exists $anvil->data->{sys}{network}{interface}{$interface})
{ {
@ -100,12 +99,8 @@ sub report_network
if (-e $mac_bond_file) if (-e $mac_bond_file)
{ {
# It's a slave. # It's a slave.
$is_slave = 1;
$mac_address = $anvil->Storage->read_file({file => $mac_bond_file}); $mac_address = $anvil->Storage->read_file({file => $mac_bond_file});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { mac_address => $mac_address }});
is_slave => $is_slave,
mac_address => $mac_address,
}});
} }
# If this is a virtual interface, set some fake values that don't actually exist on # If this is a virtual interface, set some fake values that don't actually exist on
@ -133,19 +128,18 @@ sub report_network
{ {
# Yup, we'll neet to dig into the bond proc files to get the proper slaved # Yup, we'll neet to dig into the bond proc files to get the proper slaved
# interface MAC addresses. # interface MAC addresses.
$is_bond = 1; $type = "bond";
} }
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
duplex => $duplex, duplex => $duplex,
interface => $interface, interface => $interface,
ip_address => $ip_address,
link_state => $link_state,
mac_address => $mac_address, mac_address => $mac_address,
mtu => $mtu, mtu => $mtu,
operational => $operational, operational => $operational,
speed => $speed, speed => $speed,
subnet_mask => $subnet_mask, subnet_mask => $subnet_mask,
type => $type,
}}); }});
# If the MAC address starts with '52:54:00', we've got a virtio NIC. # If the MAC address starts with '52:54:00', we've got a virtio NIC.
@ -183,8 +177,6 @@ sub report_network
$anvil->data->{network}{interfaces}{by_name}{$interface} = { $anvil->data->{network}{interfaces}{by_name}{$interface} = {
duplex => $duplex, duplex => $duplex,
ip_address => $ip_address, ip_address => $ip_address,
is_bond => $is_bond,
is_slave => $is_slave,
link_state => $link_state, link_state => $link_state,
mac_address => $mac_address, mac_address => $mac_address,
media => $media, media => $media,
@ -192,12 +184,11 @@ sub report_network
operational => $operational, operational => $operational,
speed => $speed, speed => $speed,
subnet_mask => $subnet_mask, subnet_mask => $subnet_mask,
type => $type,
}; };
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"network::interfaces::by_name::${interface}::duplex" => $duplex, "network::interfaces::by_name::${interface}::duplex" => $duplex,
"network::interfaces::by_name::${interface}::ip_address" => $ip_address, "network::interfaces::by_name::${interface}::ip_address" => $ip_address,
"network::interfaces::by_name::${interface}::is_bond" => $is_bond,
"network::interfaces::by_name::${interface}::is_slave" => $is_slave,
"network::interfaces::by_name::${interface}::link_state" => $link_state, "network::interfaces::by_name::${interface}::link_state" => $link_state,
"network::interfaces::by_name::${interface}::mac_address" => $mac_address, "network::interfaces::by_name::${interface}::mac_address" => $mac_address,
"network::interfaces::by_name::${interface}::media" => $media, "network::interfaces::by_name::${interface}::media" => $media,
@ -205,6 +196,7 @@ sub report_network
"network::interfaces::by_name::${interface}::operational" => $operational, "network::interfaces::by_name::${interface}::operational" => $operational,
"network::interfaces::by_name::${interface}::speed" => $speed, "network::interfaces::by_name::${interface}::speed" => $speed,
"network::interfaces::by_name::${interface}::subnet_mask" => $subnet_mask, "network::interfaces::by_name::${interface}::subnet_mask" => $subnet_mask,
"network::interfaces::by_name::${interface}::type" => $type,
}}); }});
} }
} }
@ -212,33 +204,37 @@ sub report_network
foreach my $interface (sort {$a cmp $b} keys %{$anvil->data->{network}{interfaces}{by_name}}) foreach my $interface (sort {$a cmp $b} keys %{$anvil->data->{network}{interfaces}{by_name}})
{ {
my $duplex = $anvil->data->{network}{interfaces}{by_name}{$interface}{duplex}; my $duplex = $anvil->data->{network}{interfaces}{by_name}{$interface}{duplex};
my $ip_address = $anvil->data->{network}{interfaces}{by_name}{$interface}{ip_address}; my $ip_address = $anvil->data->{network}{interfaces}{by_name}{$interface}{ip_address};
my $is_bond = $anvil->data->{network}{interfaces}{by_name}{$interface}{is_bond}; my $link_state = $anvil->data->{network}{interfaces}{by_name}{$interface}{link_state};
my $is_slave = $anvil->data->{network}{interfaces}{by_name}{$interface}{is_slave}; my $mac_address = $anvil->data->{network}{interfaces}{by_name}{$interface}{mac_address};
my $link_state = $anvil->data->{network}{interfaces}{by_name}{$interface}{link_state}; my $media = $anvil->data->{network}{interfaces}{by_name}{$interface}{media};
my $mac_address = $anvil->data->{network}{interfaces}{by_name}{$interface}{mac_address}; my $mtu = $anvil->data->{network}{interfaces}{by_name}{$interface}{mtu};
my $media = $anvil->data->{network}{interfaces}{by_name}{$interface}{media}; my $operational = $anvil->data->{network}{interfaces}{by_name}{$interface}{operational};
my $mtu = $anvil->data->{network}{interfaces}{by_name}{$interface}{mtu}; my $speed = $anvil->data->{network}{interfaces}{by_name}{$interface}{speed};
my $operational = $anvil->data->{network}{interfaces}{by_name}{$interface}{operational}; my $subnet_mask = $anvil->data->{network}{interfaces}{by_name}{$interface}{subnet_mask};
my $speed = $anvil->data->{network}{interfaces}{by_name}{$interface}{speed}; my $type = $anvil->data->{network}{interfaces}{by_name}{$interface}{type};
my $subnet_mask = $anvil->data->{network}{interfaces}{by_name}{$interface}{subnet_mask}; my $default_gateway = $anvil->data->{sys}{network}{interface}{$interface}{default_gateway};
my $gateway = $anvil->data->{sys}{network}{interface}{$interface}{gateway};
my $dns = $anvil->data->{sys}{network}{interface}{$interface}{dns};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
duplex => $duplex, default_gateway => $default_gateway,
interface => $interface, dns => $dns,
ip_address => $ip_address, duplex => $duplex,
is_bond => $is_bond, gateway => $gateway,
is_slave => $is_slave, interface => $interface,
link_state => $link_state, ip_address => $ip_address,
mac_address => $mac_address, link_state => $link_state,
media => $media, mac_address => $mac_address,
mtu => $mtu, media => $media,
operational => $operational, mtu => $mtu,
speed => $speed, operational => $operational,
subnet_mask => $subnet_mask, speed => $speed,
subnet_mask => $subnet_mask,
type => $type,
}}); }});
# $anvil->Database->insert_or_update_network_interfaces({ # my $network_interface_uuid = $anvil->Database->insert_or_update_network_interfaces({
# file => $THIS_FILE, # file => $THIS_FILE,
# line => __LINE__, # line => __LINE__,
# network_interface_name => $interface, # network_interface_name => $interface,
@ -249,6 +245,16 @@ sub report_network
# network_interface_medium => $media, # network_interface_medium => $media,
# network_interface_mtu => $mtu, # network_interface_mtu => $mtu,
# network_interface_speed => $speed, # network_interface_speed => $speed,
# });
#
# my $ip_address_uuid = $anvil->Database->insert_or_update_ip_addresses({
# ip_address_on_type => $ip_address_on_type,
# ip_address_on_uuid => $ip_address_on_uuid,
# ip_address_address => $ip_address_address,
# ip_address_subnet => $ip_address_subnet,
# ip_address_gateway => $ip_address_gateway,
# ip_address_default_gateway => $ip_address_default_gateway,
# ip_address_dns => $ip_address_dns,
# }); # });
} }

@ -655,6 +655,76 @@ CREATE TRIGGER trigger_bridges
FOR EACH ROW EXECUTE PROCEDURE history_bridges(); FOR EACH ROW EXECUTE PROCEDURE history_bridges();
-- This stores information about network ip addresss.
CREATE TABLE ip_addresses (
ip_address_uuid uuid not null primary key,
ip_address_host_uuid uuid not null,
ip_address_on_type text not null, -- Either 'interface', 'bond' or 'bridge'
ip_address_on_uuid uuid not null, -- This is the UUID of the interface, bond or bridge that has this IP
ip_address_address text not null, -- The actual IP address
ip_address_subnet text not null, -- The subnet mask (in dotted decimal format)
ip_address_gateway text, -- If set, this is the gateway IP for this subnet
ip_address_default_gateway boolean default FALSE, -- If true, the gateway will be the default for the host.
ip_address_dns text, -- If set, this is a comma-separated list of DNS IPs to use (in the order given)
modified_date timestamp with time zone not null,
FOREIGN KEY(ip_address_host_uuid) REFERENCES hosts(host_uuid)
);
ALTER TABLE ip_addresses OWNER TO #!variable!user!#;
CREATE TABLE history.ip_addresses (
history_id bigserial,
ip_address_uuid uuid,
ip_address_host_uuid uuid,
ip_address_on_type text,
ip_address_on_uuid uuid,
ip_address_address text,
ip_address_subnet text,
ip_address_gateway text,
ip_address_default_gateway text,
ip_address_dns text,
modified_date timestamp with time zone not null
);
ALTER TABLE history.ip_addresses OWNER TO #!variable!user!#;
CREATE FUNCTION history_ip_addresses() RETURNS trigger
AS $$
DECLARE
history_ip_addresses RECORD;
BEGIN
SELECT INTO history_ip_addresses * FROM ip_addresses WHERE ip_address_uuid = new.ip_address_uuid;
INSERT INTO history.ip_addresses
(ip_address_uuid,
ip_address_host_uuid,
ip_address_on_type,
ip_address_on_uuid,
ip_address_address,
ip_address_subnet,
ip_address_gateway,
ip_address_default_gateway,
ip_address_dns,
modified_date)
VALUES
(history_ip_addresses.ip_address_uuid,
history_ip_addresses.ip_address_host_uuid,
history_ip_addresses.ip_address_on_type,
history_ip_addresses.ip_address_on_uuid,
history_ip_addresses.ip_address_address,
history_ip_addresses.ip_address_subnet,
history_ip_addresses.ip_address_gateway,
history_ip_addresses.ip_address_default_gateway,
history_ip_addresses.ip_address_dns,
history_ip_addresses.modified_date);
RETURN NULL;
END;
$$
LANGUAGE plpgsql;
ALTER FUNCTION history_ip_addresses() OWNER TO #!variable!user!#;
CREATE TRIGGER trigger_ip_addresses
AFTER INSERT OR UPDATE ON ip_addresses
FOR EACH ROW EXECUTE PROCEDURE history_ip_addresses();
-- ------------------------------------------------------------------------------------------------------- -- -- ------------------------------------------------------------------------------------------------------- --
-- These are special tables with no history or tracking UUIDs that simply record transient information. -- -- These are special tables with no history or tracking UUIDs that simply record transient information. --

Loading…
Cancel
Save