Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

aii-dhcp: support optional hostname ip verification #299

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions aii-core/src/main/perl/Shellfe.pm
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ use constant USEMODULE => "use " . MODULEBASE;
use constant PROFILEINFO => 'profiles-info.xml';

use constant NODHCP => 'nodhcp';
use constant DISCOVERY => '/system/aii/discovery';
use constant OSINSTALL => '/system/aii/osinstall';
use constant NBP => '/system/aii/nbp';
use constant CDBURL => 'cdburl';
Expand Down Expand Up @@ -608,6 +609,14 @@ sub dhcp
my ($self, $st, $cmd, $dhcpmgr) = @_;

my $name = $st->{name};

# If the profile has a discovery plugin configured, then don't second-guess
# it - it may or may not be ISC DHCP
if ($st->{configuration}->elementExists(DISCOVERY)) {
$self->verbose("Found discovery configuration for path ".DISCOVERY." for $name. Skipping");
return;
};

my $tree = $st->{configuration}->getTree(DHCPPATH);
if (! $tree) {
$self->verbose("No configuration for DHCP path ".DHCPPATH." for $name. Skipping");
Expand Down
41 changes: 24 additions & 17 deletions aii-dhcp/src/main/pan/quattor/aii/dhcp/config.pan
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,31 @@
# ${developer-info}
# ${author-info}
# ${build-info}
template quattor/aii/${project.artifactId}/config;
template quattor/aii/dhcp/config;

include 'quattor/aii/${project.artifactId}/schema';
include 'quattor/aii/dhcp/schema';

# TFTP server
# This is optional. Only it is necessary if your TFTP server is running on
# a different machine than the DHCP server
#
# "/system/aii/dhcp/options/tftpserver" = "tftp.mydomain.org"
#
bind "/system/aii/discovery/dhcp" = structure_dhcp_module_info;

prefix "/system/aii/discovery/dhcp";

@documentation{
Enable the plugin
}
"enabled" = true;

bind "/system/aii/dhcp" = structure_dhcp_dhcp_info;

prefix "/system/aii/dhcp";

@documentation{
Override the TFT server for this node
}
variable AII_DHCP_TFTPSERVER ?= null;
"/system/aii/dhcp/options/tftpserver" ?= AII_DHCP_TFTPSERVER;

# Additional DHCP options (optional).
# Warning: They will be added in the host declaration of dhcpd.conf file, so
# do not forget the ';' at the end
#
#"/system/aii/dhcp/addoptions" = "options blu-blo-bli bla;";
#
"tftpserver" ?= AII_DHCP_TFTPSERVER;

@documentation{
Additional options to include in the host definition
}
variable AII_DHCP_ADDOPTIONS ?= null;
"/system/aii/dhcp/options/addoptions" ?= AII_DHCP_ADDOPTIONS;
"options" ?= AII_DHCP_ADDOPTIONS;
Empty file modified aii-dhcp/src/main/pan/quattor/aii/dhcp/rpms.pan
100755 → 100644
Empty file.
19 changes: 15 additions & 4 deletions aii-dhcp/src/main/pan/quattor/aii/dhcp/schema.pan
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,23 @@
# ${author-info}
# ${build-info}

unique template quattor/aii/${project.artifactId}/schema;
unique template quattor/aii/dhcp/schema;

type structure_dhcp_module_info = {
"enabled" ? boolean
};

# Information needed for creating the Kickstart file
type structure_dhcp_dhcp_info = {
@{TFTP server to use for this node, instead of the host where AII runs}
"tftpserver" ? string
@{Name of the file to boot}
"filename" ? string
@{
Custom options to include in the host definition. Note: if the type
of an option requires quoting, then the quotes must be included in
the value you specify in templates.
}
"options" ? string{}
@{Verify hostname in DNS}
"verifyhostname" ? boolean
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this should be choice("yes", "no", "strict") instead of a boolean, where strict would cause the component to fail if gethostbyname() below fails. Usually, not having a hard dependency on DNS being up-to-date is good, but I can think of a few use cases where it would be useful if AII could send the message: You need to wait for DNS to get updated, because otherwise the build will fail later anyway.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@stdweird any thoughts?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wow, this is long time ago.
sure, but perhaps then choice("yes", "no", "warning") or something. or check_only instead of warning.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah too long ago really, sorry 😞

My vote is for "warn".

};

bind "/system/aii/${project.artifactId}" = structure_dhcp_dhcp_info;
59 changes: 43 additions & 16 deletions aii-dhcp/src/main/perl/dhcp.pm
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use Socket;
use Exporter;
use Sys::Hostname;
use CAF::Lock qw (FORCE_IF_STALE);
use CAF::FileReader;
use CAF::FileWriter;
use CAF::Process;

Expand Down Expand Up @@ -70,7 +71,7 @@ sub update_dhcp_config_file
$nodes_regexp .= $node->{NAME} . '|' . $node->{FQDN} . '|';
}
$nodes_regexp =~ s/\|$//; # remove last '|'
$nodes_regexp = '\\n\s*host\s+(' . $nodes_regexp . ')\s*\{[^}]*\}';
$nodes_regexp = '\\n\s*host\s+(' . $nodes_regexp . ')\s*(\{(?:[^{}]|(?2))*\})';
$text =~ s/$nodes_regexp//gm;

#
Expand Down Expand Up @@ -138,6 +139,11 @@ sub update_dhcp_config_file
push @newnodes, "$indent\t next-server $node->{ST_IP_TFTP};";
}

# DHCP filename option
if ($node->{FILENAME}) {
push @newnodes, "$indent\t filename \"$node->{FILENAME}\";";
}

# additional options
if ($node->{MORE_OPT}) {
push @newnodes, "$indent\t $node->{MORE_OPT}";
Expand Down Expand Up @@ -255,14 +261,14 @@ sub update_dhcp_config {
}
$self->debug(3, "Locked dhcp configuration");
$self->debug(3,"DHCP configuration file : $filename");
if (!open(FILE, "< $filename")) {
my $fh = CAF::FileReader->new($filename, log => $self);
if ($EC->error()) {
$self->error("dhcp: update configuration: ".
"file access error $filename");
return(1);
}
local $/ = undef;
$text = <FILE>;
close (FILE);
$text = "$fh";
$fh->close();

#
# Add/removal of nodes
Expand All @@ -272,18 +278,10 @@ sub update_dhcp_config {
return(1);
}

#
# Backup the old one
#
if (!rename ($filename, $filename . '.pre_aii')) {
$self->error("dhcp: error creating backup copy $filename.pre_aii");
return(1);
}

#
# Write the new dhcp configuration file
#
my $file = CAF::FileWriter->open($filename, mode => 0664, log => $this_app);
my $file = CAF::FileWriter->new($filename, mode => 0664, log => $this_app, backup => '.pre_aii');
$file->print($text);
$file->close();

Expand All @@ -297,6 +295,9 @@ sub Configure

my $tree = $config->getElement("/system/network")->getTree();
my $fqdn = $tree->{hostname} . "." . $tree->{domainname};

my $opts = $config->getElement("/system/aii/dhcp")->getTree();

# Find the bootable interface
my $cards = $config->getElement("/hardware/cards/nic")->getTree();
my $bootable = undef;
Expand All @@ -312,12 +313,37 @@ sub Configure
}
my $ip = $self->get_ip($bootable, $tree);

my $opts = $config->getElement("/system/aii/dhcp")->getTree();
if ($opts->{verifyhostname}) {
my $fqdn_ip = gethostbyname($fqdn);
$fqdn_ip = inet_ntoa($fqdn_ip) if defined($fqdn_ip);
if (defined($fqdn_ip)) {
if ($fqdn_ip ne $ip) {
$self->error("aii-dhcp: fqdn $fqdn ip $fqdn_ip does not match configured ip $ip");
}
} else {
$self->error("aii-dhcp: failed to obtain IP address for fqdn $fqdn");
return;
}
}


my $server_ip = gethostbyname(hostname());
$server_ip = inet_ntoa($server_ip) if defined($server_ip);
if (!defined($server_ip)) {
$self->error("aii-dhcp: failed to obtain own IP address");
return;
}

my $tftpserver = "";
my $filename = "";
my $additional = "";
if ($opts->{tftpserver}) {
$tftpserver = $opts->{tftpserver};
}
if ($opts->{filename}) {
$filename = $opts->{filename};
$filename =~ s/BOOTSRVIP/$server_ip/;
}
if ($opts->{options}) {
foreach my $k (sort keys %{$opts->{options}}) {
$additional .= "option $k $opts->{options}->{$k};\n";
Expand All @@ -331,6 +357,7 @@ sub Configure
IP => unpack('N', Socket::inet_aton($ip)),
MAC => $cards->{$bootable}->{hwaddr},
ST_IP_TFTP => $tftpserver,
FILENAME => $filename,
MORE_OPT => $additional,
};
if ($this_app->option('use_fqdn')) {
Expand Down Expand Up @@ -373,7 +400,7 @@ sub Unconfigure
IP => $ip,
};
$self->update_dhcp_config([], [$nodeconfig]);
return 0;
return 1;
}

1;
Empty file modified aii-dhcp/src/main/perl/dhcp.pod
100755 → 100644
Empty file.
Loading