in managementnode/lib/VCL/Module/OS/Linux/ManagementNode.pm [761:861]
sub generate_private_key_file {
my $self = shift;
if (ref($self) !~ /VCL::Module/i) {
notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a function, it must be called as a class method");
return;
}
my $arguments_hash_ref = shift;
if (defined($arguments_hash_ref) && !ref($arguments_hash_ref) || ref($arguments_hash_ref) ne 'HASH') {
notify($ERRORS{'WARNING'}, 0, "argument was supplied but is not a hash reference:\n" . format_data($arguments_hash_ref));
return;
}
my $private_key_file_path = $self->get_private_key_file_path();
my $bits = 4096;
# If provided and true, existing private key file will be deleted if it exists
my $force = $arguments_hash_ref->{force};
my $management_node_id = $self->data->get_management_node_id() || return;
my $management_node_short_name = $self->data->get_management_node_short_name() || return;
my $reservation_id = $self->data->get_reservation_id();
notify($ERRORS{'DEBUG'}, 0, "*** attempting to generate a new private key file on $management_node_short_name: $private_key_file_path ***");
# Make sure the private key file does not already exist
if ($self->file_exists($private_key_file_path)) {
if ($force) {
(my $timestamp = makedatestring()) =~ s/\s+/_/g;
my $backup_private_key_file_path = $private_key_file_path . "_$timestamp";
if ($self->copy_file($private_key_file_path, $backup_private_key_file_path)) {
notify($ERRORS{'OK'}, 0, "force argument was specified, existing private key file will be overwritten, created backup copy: $private_key_file_path --> $backup_private_key_file_path");
}
else {
notify($ERRORS{'WARNING'}, 0, "failed to generate encryption keys, force argument was specified, existing private key file exists but failed to create backup copy: $private_key_file_path --> $backup_private_key_file_path");
return;
}
}
else {
notify($ERRORS{'WARNING'}, 0, "failed to generate encryption keys, private key file already exists: $private_key_file_path");
return;
}
}
# Delete cached RSA object
if ($self->{private_key_object_from_file}) {
notify($ERRORS{'DEBUG'}, 0, "deleting cached RSA private key object");
delete $self->{private_key_object_from_file};
}
# Delete all existing cryptsecret entries for the management node
# The website's API won't delete any that may have been created with an earlier key
delete_management_node_cryptsecret($management_node_id);
# Override the die handler
local $SIG{__DIE__} = sub{};
# Create a new RSA object containing a private/public key pair
# Create an RSA object based on the existing private key contained in the file
my $rsa_generate;
eval {
$rsa_generate = Crypt::OpenSSL::RSA->generate_key($bits);
};
if ($EVAL_ERROR || !$rsa_generate) {
notify($ERRORS{'WARNING'}, 0, "failed to create private key file on management node $management_node_short_name: $private_key_file_path, RSA object could not be created" . ($EVAL_ERROR ? ", error:\n" . $EVAL_ERROR : ''));
return;
}
my $private_key_string;
eval {
$private_key_string = $rsa_generate->get_private_key_string();
};
if ($EVAL_ERROR || !$private_key_string) {
notify($ERRORS{'WARNING'}, 0, "failed to create private key file on management node $management_node_short_name: $private_key_file_path, private key string could not be retireved from RSA object" . ($EVAL_ERROR ? ", error:\n" . $EVAL_ERROR : ''));
return;
}
my $public_key_string;
eval {
$public_key_string = $rsa_generate->get_public_key_x509_string();
};
if ($EVAL_ERROR || !$public_key_string) {
notify($ERRORS{'WARNING'}, 0, "failed to create private key file on management node $management_node_short_name: $private_key_file_path, public key string could not be retireved from RSA object" . ($EVAL_ERROR ? ", error:\n" . $EVAL_ERROR : ''));
return;
}
$self->create_text_file($private_key_file_path, $private_key_string) || return;
# Update cryptkey table with the public key string
if (!set_management_node_cryptkey_pubkey($management_node_id, $public_key_string)) {
notify($ERRORS{'WARNING'}, 0, "created private key file on management node $management_node_short_name: $private_key_file_path, failed to update cryptkey table in database, attempting to delete private key file just created: $private_key_file_path");
$self->delete_file($private_key_file_path);
return;
}
# Call the XML-RPC API to create a new cryptsecret entry for this reservation
call_check_crypt_secrets($reservation_id);
notify($ERRORS{'OK'}, 0, "created private key file on management node $management_node_short_name: $private_key_file_path, updated cryptkey.pubkey value in database");
return 1;
}