You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@vcl.apache.org by ar...@apache.org on 2010/01/11 19:14:14 UTC

svn commit: r897984 - /incubator/vcl/trunk/managementnode/lib/VCL/Module/OS/Windows.pm

Author: arkurth
Date: Mon Jan 11 18:14:14 2010
New Revision: 897984

URL: http://svn.apache.org/viewvc?rev=897984&view=rev
Log:
VCL-145
Added get_product_key, set_product_key, get_kms_servers, and set_kms_server subroutines to Windows.pm. They get/set data from the winProductKey and winKMS tables.

Modified:
    incubator/vcl/trunk/managementnode/lib/VCL/Module/OS/Windows.pm

Modified: incubator/vcl/trunk/managementnode/lib/VCL/Module/OS/Windows.pm
URL: http://svn.apache.org/viewvc/incubator/vcl/trunk/managementnode/lib/VCL/Module/OS/Windows.pm?rev=897984&r1=897983&r2=897984&view=diff
==============================================================================
--- incubator/vcl/trunk/managementnode/lib/VCL/Module/OS/Windows.pm (original)
+++ incubator/vcl/trunk/managementnode/lib/VCL/Module/OS/Windows.pm Mon Jan 11 18:14:14 2010
@@ -8150,6 +8150,462 @@
 
 #/////////////////////////////////////////////////////////////////////////////
 
+=head2 get_product_key
+
+ Parameters  : $affiliation_identifier (optional), $product_name (optional)
+ Returns     : If successful: string containing product key
+               If failed: false
+ Description : Retrieves the Windows product key from the database. This is
+               stored in the winProductKey table.
+               
+               Optional affiliation identifier and product name arguments may be
+               passed. Either both arguments must be passed or none. The
+               affiliation identifier may either be an affiliation ID or name.
+               If passed, the only data returned will be the data matching that
+               specific identifier. Global affiliation data will not be
+               returned.
+               
+               If the affiliation identifier argument is not passed, the
+               affiliation is determined by the affiliation of the owner of the
+               image for the reservation. If a product key has not been
+               configured for that specific affiliation, the product key
+               configured for the Global affiliation is returned.
+
+=cut
+
+sub get_product_key {
+	my $self = shift;
+	if (ref($self) !~ /windows/i) {
+		notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a function, it must be called as a class method");
+		return;
+	}
+	
+	# Remember if this sub was called with arguments
+	# Used to determine whether or not Global activation data will be checked
+	# If affiliation ID argument is specified, assume caller only wants the data for that affiliation and not the Global data
+	my $include_global;
+	if (scalar(@_) == 2) {
+		$include_global = 0;
+		notify($ERRORS{'DEBUG'}, 0, "subroutine was called with arguments, global affiliation data will be ignored");
+	}
+	elsif (scalar(@_) == 0) {
+		$include_global = 1;
+		notify($ERRORS{'DEBUG'}, 0, "subroutine was NOT called with arguments, global affiliation data will be included");
+	}
+	else {
+		notify($ERRORS{'WARNING'}, 0, "subroutine argument count = " . scalar(@_) . ", it must only be called with 0 or 2 arguments");
+		return;
+	}
+	
+	# Get the affiliation identifer, may be ID or name
+	my $affiliation_identifier = shift;
+	if (!defined($affiliation_identifier)) {
+		$affiliation_identifier = $self->data->get_image_affiliation_id();
+	}
+	if (!defined($affiliation_identifier)) {
+		notify($ERRORS{'WARNING'}, 0, "affiliation identifier argument was not passed and could not be determined from image");
+		return;
+	}
+	
+	# Get the product name, could be:
+	# "Microsoft Windows XP"
+	# "Microsoft Windows Server 2003"
+	my $product_name = shift || $self->get_product_name();
+	if ($product_name) {
+		notify($ERRORS{'DEBUG'}, 0, "product name: $product_name");
+	}
+	else {
+		notify($ERRORS{'WARNING'}, 0, "product name argument was not passed and could not be determined from computer");
+		return;
+	}
+	
+	# Create the affiliation-specific select statement
+	# Check if the affiliation identifier is a number or word
+	# If a number, use affiliation.id directly
+	# If a word, reference affiliation.name
+	my $affiliation_select_statement;
+	if ($affiliation_identifier =~ /^\d+$/) {
+		notify($ERRORS{'DEBUG'}, 0, "affiliation identifier is a number, retrieving winProductKey.affiliationid=$affiliation_identifier");
+		$affiliation_select_statement = <<EOF;
+SELECT
+winProductKey.*
+FROM
+winProductKey
+WHERE
+winProductKey.productname LIKE '$product_name'
+AND winProductKey.affiliationid = $affiliation_identifier
+EOF
+	}
+	else {
+		notify($ERRORS{'DEBUG'}, 0, "affiliation identifier is NOT a number, retrieving affiliation.name=$affiliation_identifier");
+		$affiliation_select_statement = <<EOF;
+SELECT
+winProductKey.*
+FROM
+winProductKey,
+affiliation
+WHERE
+winProductKey.productname LIKE '$product_name'
+AND winProductKey.affiliationid = affiliation.id
+AND affiliation.name LIKE '$affiliation_identifier'
+EOF
+	}
+	
+	# Create the select statement
+	my $global_select_statement = <<EOF;
+SELECT
+winProductKey.*
+FROM
+winProductKey,
+affiliation
+WHERE
+winProductKey.productname LIKE '$product_name'
+AND winProductKey.affiliationid = affiliation.id
+AND affiliation.name LIKE 'Global'
+EOF
+	
+	# Call the database select subroutine
+	my @affiliation_rows = database_select($affiliation_select_statement);
+	
+	# Get the rows for the Global affiliation if this subroutine wasn't called with arguments
+	my @global_rows = ();
+	if ($include_global) {
+		@global_rows = database_select($global_select_statement);
+	}
+	
+	# Create an array containing the combined rows
+	my @combined_rows = (@affiliation_rows, @global_rows);
+
+	# Check to make sure rows were returned
+	if (!@combined_rows) {
+		notify($ERRORS{'WARNING'}, 0, "0 rows were retrieved from winProductKey table for affiliation=$affiliation_identifier, product=$product_name");
+		return;
+	}
+	notify($ERRORS{'DEBUG'}, 0, "retrieved rows from winProductKey table for affiliation=$affiliation_identifier, product=$product_name:\n" . format_data(\@combined_rows));
+	
+	my $product_key = $combined_rows[0]->{productkey};
+	notify($ERRORS{'DEBUG'}, 0, "returning product key: $product_key");
+	
+	return $product_key;
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 set_product_key
+
+ Parameters  : $affiliation_id, $product_name, $product_key
+ Returns     : If successful: true
+               If failed: false
+ Description : Inserts or updates a row in the winKMS table in the database.
+
+=cut
+
+sub set_product_key {
+	my $self = shift;
+	if (ref($self) !~ /windows/i) {
+		notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a function, it must be called as a class method");
+		return;
+	}
+	
+	# Get and check the arguments
+	my ($affiliation_identifier, $product_name, $product_key) = @_;
+	if (!defined($affiliation_identifier) || !defined($product_name) || !defined($product_key)) {
+		notify($ERRORS{'WARNING'}, 0, "affiliation ID, product name, and product key arguments not passed correctly");
+		return;
+	}
+	
+	# Create the insert statement
+	# Check if the affiliation identifier is a number or word
+	# If a number, set affiliation.id directly
+	# If a word, reference affiliation.name
+	my $insert_statement;
+	if ($affiliation_identifier =~ /^\d+$/) {
+		notify($ERRORS{'DEBUG'}, 0, "affiliation identifier is a number, setting winProductKey.affiliationid=$affiliation_identifier");
+		$insert_statement = <<"EOF";
+INSERT INTO winProductKey
+(
+affiliationid,
+productname,
+productkey
+)
+VALUES
+(
+'$affiliation_identifier',
+'$product_name',
+'$product_key'
+)
+ON DUPLICATE KEY UPDATE
+affiliationid=VALUES(affiliationid),
+productname=VALUES(productname),
+productkey=VALUES(productkey)
+EOF
+	}
+	else {
+		notify($ERRORS{'DEBUG'}, 0, "affiliation identifier is NOT a number, setting affiliation.name=$affiliation_identifier");
+		$insert_statement = <<"EOF";
+INSERT INTO winProductKey
+(
+affiliationid,
+productname,
+productkey
+)
+VALUES
+(
+(SELECT id FROM affiliation WHERE name='$affiliation_identifier'),
+'$product_name',
+'$product_key'
+)
+ON DUPLICATE KEY UPDATE
+affiliationid=VALUES(affiliationid),
+productname=VALUES(productname),
+productkey=VALUES(productkey)
+EOF
+	}
+	
+	# Execute the insert statement, the return value should be the id of the row
+	my $insert_result = database_execute($insert_statement);
+	if (defined($insert_result)) {
+		notify($ERRORS{'DEBUG'}, 0, "set product key in database:\naffiliation ID: $affiliation_identifier\nproduct name: $product_name\nproduct key: $product_key");
+	
+	}
+	else {
+		notify($ERRORS{'WARNING'}, 0, "failed to set product key in database:\naffiliation ID: $affiliation_identifier\nproduct name: $product_name\nproduct key: $product_key");
+		return;
+	}
+	
+	return 1;
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 get_kms_servers
+
+ Parameters  : $affiliation_identifier (optional)
+ Returns     : If successful: reference to array of hashes
+               If failed: false
+ Description : Retrieves the KMS server data from the database. This is
+               stored in the winKMS table.
+               
+               An optional affiliation identifier argument may be passed. This
+               may either be an affiliation ID or name. If passed, the only data
+               returned will be the data matching that specific identifier.
+               Global affiliation data will not be returned.
+               
+               If the affiliation identifier argument is not passed, the
+               affiliation is determined by the affiliation of the owner of the
+               image for the reservation. If a KMS server has not been
+               configured for that specific affiliation, the KMS server
+               configured for the Global affiliation is returned.
+               
+               This subroutine returns an array reference. Each array element
+               contains a hash reference representing a row in the winKMS table.
+               
+               Example of returned data:
+               @{$kms_servers}[0] =
+                  |--{address} = 'kms.affiliation.edu'
+                  |--{affiliationid} = '1'
+                  |--{port} = '1688'
+               @{$kms_servers}[1] =
+                  |--{address} = 'kms.global.edu'
+                  |--{affiliationid} = '0'
+                  |--{port} = '1688'
+                  
+               Example usage:
+               my $kms_servers = $self->os->get_kms_servers();
+               my $kms_address = @{$kms_servers[0]}->{address};
+
+=cut
+
+sub get_kms_servers {
+	my $self = shift;
+	if (ref($self) !~ /windows/i) {
+		notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a function, it must be called as a class method");
+		return;
+	}
+	
+	# Remember if this sub was called with arguments
+	# Used to determine whether or not global affiliation data will be checked
+	my $include_global;
+	if (scalar(@_) == 1) {
+		$include_global = 0;
+		notify($ERRORS{'DEBUG'}, 0, "subroutine was called with an affiliation argument, global affiliation data will be ignored");
+	}
+	elsif (scalar(@_) == 0) {
+		$include_global = 1;
+		notify($ERRORS{'DEBUG'}, 0, "subroutine was NOT called with arguments, global affiliation data will be included");
+	}
+	else {
+		notify($ERRORS{'WARNING'}, 0, "subroutine argument count = " . scalar(@_) . ", it must only be called with 0 or 1 arguments");
+		return;
+	}
+	
+	# Get the image affiliation identifier, may be ID or name
+	my $affiliation_identifier = shift;
+	if (!defined($affiliation_identifier)) {
+		$affiliation_identifier = $self->data->get_image_affiliation_id();
+	}
+	if (!defined($affiliation_identifier)) {
+		notify($ERRORS{'WARNING'}, 0, "affiliation argument was not passed and could not be determined from image");
+		return;
+	}
+	
+	# Create the affiliation-specific select statement
+	# Check if the affiliation identifier is a number or word
+	# If a number, use affiliation.id directly
+	# If a word, reference affiliation.name
+	my $affiliation_select_statement;
+	if ($affiliation_identifier =~ /^\d+$/) {
+		notify($ERRORS{'DEBUG'}, 0, "affiliation identifier is a number, retrieving winKMS.affiliationid=$affiliation_identifier");
+		$affiliation_select_statement = <<EOF;
+SELECT
+winKMS.*
+FROM
+winKMS
+WHERE
+winKMS.affiliationid = $affiliation_identifier
+EOF
+	}
+	else {
+		notify($ERRORS{'DEBUG'}, 0, "affiliation identifier is NOT a number, retrieving affiliation.name=$affiliation_identifier");
+		$affiliation_select_statement .= <<EOF;
+SELECT
+winKMS.*
+FROM
+winKMS,
+affiliation
+WHERE
+winKMS.affiliationid = affiliation.id
+AND affiliation.name LIKE '$affiliation_identifier'
+EOF
+	}
+	
+	# Create the Global affiliation select statement
+	my $global_select_statement .= <<EOF;
+SELECT
+winKMS.*
+FROM
+winKMS,
+affiliation
+WHERE
+winKMS.affiliationid = affiliation.id
+AND affiliation.name LIKE 'Global'
+EOF
+
+	# Call the database select subroutine
+	my @affiliation_rows = database_select($affiliation_select_statement);
+	
+	# Get the rows for the Global affiliation if this subroutine wasn't called with arguments
+	my @global_rows = ();
+	if ($include_global) {
+		@global_rows = database_select($global_select_statement);
+	}
+	
+	# Create an array containing the combined rows
+	my @combined_rows = (@affiliation_rows, @global_rows);
+
+	# Check to make sure rows were returned
+	if (!@combined_rows) {
+		notify($ERRORS{'WARNING'}, 0, "0 rows were retrieved from winKMS table for affiliation=$affiliation_identifier");
+		return;
+	}
+	
+	notify($ERRORS{'DEBUG'}, 0, "returning row array from winKMS table for affiliation=$affiliation_identifier:\n" . format_data(\@combined_rows));
+	return \@combined_rows;
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 set_kms_server
+
+ Parameters  : $affiliation_id, $address, $port (optional)
+ Returns     : If successful: true
+               If failed: false
+ Description : Inserts or updates a row in the winKMS table in the database.
+
+=cut
+
+sub set_kms_server {
+	my $self = shift;
+	if (ref($self) !~ /windows/i) {
+		notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a function, it must be called as a class method");
+		return;
+	}
+	
+	# Get and check the arguments
+	my ($affiliation_identifier, $address, $port) = @_;
+	if (!defined($affiliation_identifier) || !defined($address)) {
+		notify($ERRORS{'WARNING'}, 0, "affiliation ID and KMS address arguments not passed correctly");
+		return;
+	}
+	
+	# Set the default port if argument wasn't passed
+	if (!defined($port)) {
+		$port = 1688;
+	}
+	
+		# Create the insert statement
+	# Check if the affiliation identifier is a number or word
+	# If a number, set affiliation.id directly
+	# If a word, reference affiliation.name
+	my $insert_statement;
+	if ($affiliation_identifier =~ /^\d+$/) {
+		notify($ERRORS{'DEBUG'}, 0, "affiliation identifier is a number, setting winKMS.affiliationid=$affiliation_identifier");
+		$insert_statement = <<"EOF";
+INSERT INTO winKMS
+(
+affiliationid,
+address,
+port
+)
+VALUES
+(
+'$affiliation_identifier',
+'$address',
+'$port'
+)
+ON DUPLICATE KEY UPDATE
+affiliationid=VALUES(affiliationid),
+address=VALUES(address),
+port=VALUES(port)
+EOF
+	}
+	else {
+		notify($ERRORS{'DEBUG'}, 0, "affiliation identifier is NOT a number, setting affiliation.name=$affiliation_identifier");
+		$insert_statement = <<"EOF";
+INSERT INTO winKMS
+(
+affiliationid,
+address,
+port
+)
+VALUES
+(
+(SELECT id FROM affiliation WHERE name='$affiliation_identifier'),
+'$address',
+'$port'
+)
+ON DUPLICATE KEY UPDATE
+affiliationid=VALUES(affiliationid),
+address=VALUES(address),
+port=VALUES(port)
+EOF
+	}
+
+	# Execute the insert statement, the return value should be the id of the row
+	my $insert_result = database_execute($insert_statement);
+	if (defined($insert_result)) {
+		notify($ERRORS{'OK'}, 0, "set KMS address in database:\naffiliation ID: $affiliation_identifier\naddress: $address\nport: $port");
+	}
+	else {
+		notify($ERRORS{'WARNING'}, 0, "failed to set KMS address in database:\naffiliation ID: $affiliation_identifier\naddress: $address\nport: $port");
+		return;
+	}
+	
+	return 1;
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
 1;
 __END__