#!/usr/bin/perl -w
###############################################################################
# $Id: openstack.pm 
###############################################################################
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements.  See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License.  You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
###############################################################################

=head1 NAME

VCL::Provisioning::openstack - VCL module to support the Openstack provisioning engine with REST APIs v2

=head1 SYNOPSIS

 Needs to be written

=head1 DESCRIPTION

This module provides VCL support for Openstack

=cut

###############################################################################
package VCL::Module::Provisioning::openstack;

# Include File Copying for Perl
use File::Copy;

# Specify the lib path using FindBin
use FindBin;
use lib "$FindBin::Bin/../../..";

# Configure inheritance
use base qw(VCL::Module::Provisioning);

# Specify the version of this module
our $VERSION = '2.5.1';

# Specify the version of Perl to use
use 5.008000;

use strict;
use warnings;
use diagnostics;
use English qw(-no_match_vars);
use IO::File;
use Fcntl qw(:DEFAULT :flock);
use File::Temp qw(tempfile);
use List::Util qw(max);
use VCL::utils;
use JSON qw(from_json to_json);
use LWP::UserAgent;

#//////////////////////////////////////////////////////////////////////////////

=head2 initialize

 Parameters  :
 Returns     :
 Description :

=cut

sub initialize {
	my $self = shift;
	notify($ERRORS{'DEBUG'}, 0, "OpenStack module initialized");
	
	if ($self->_set_os_auth_conf()) {
		notify($ERRORS{'OK'}, 0, "successfully set openStack auth configuration");
	}
	else {
		notify($ERRORS{'WARNING'}, 0, "failed to set openstack auth configuration");
		return 0;
	}
	
	return 1;
} ## end sub initialize


#//////////////////////////////////////////////////////////////////////////////

=head2 unload

 Parameters  : hash
 Returns     : 1(success) or 0(failure)
 Description : loads virtual machine with requested image

=cut

sub unload {
	my $self = shift;
	if (ref($self) !~ /openstack/i) {
		notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a function, it must be called as a class method");
		return;
	}

	my $computer_name = $self->data->get_computer_short_name() || return;
	my $vmhost_name = $self->data->get_vmhost_short_name() || return;
	my $computer_private_ip_address = $self->data->get_computer_private_ip_address();

	# Remove existing VMs which were created for the reservation computer
	if (_pingnode($computer_private_ip_address)) {
		if (!$self->_terminate_os_instance()) {
			notify($ERRORS{'WARNING'}, 0, "failed to delete VM $computer_name on VM host $vmhost_name");
			return 0;
		}
	}
	# Remove existing openstack id for computer mapping in database 
	# Althought the instance is not pingable (delete it accidently), it should delete the instance from database
	if (!$self->_delete_os_computer_mapping()) {
		notify($ERRORS{'WARNING'}, 0, "failed to delete the openstack instance id from openstackcomputermap");
		return 0;
	}

	return 1;

}

#//////////////////////////////////////////////////////////////////////////////

=head2 provision

 Parameters  : hash
 Returns     : 1(success) or 0(failure)
 Description : loads virtual machine with requested image

=cut

sub load {
	my $self = shift;
	if (ref($self) !~ /openstack/i) {
		notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a function, it must be called as a class method");
		return;
	}

	my $reservation_id = $self->data->get_reservation_id() || return;
	my $computer_id = $self->data->get_computer_id() || return;
	my $computer_name = $self->data->get_computer_short_name() || return;
	my $image_name = $self->data->get_image_name() || return;
	my $vmhost_name = $self->data->get_vmhost_short_name() || return;
	my $computer_private_ip_address = $self->data->get_computer_private_ip_address() || return;

	insertloadlog($reservation_id, $computer_id, "startload", "$computer_name $image_name");
	notify($ERRORS{'DEBUG'}, 0, "computer_private_ip_address = [$computer_private_ip_address]");

	# Remove existing VMs which were created for the reservation computer
	if (_pingnode($computer_private_ip_address)) {
		if (!$self->_terminate_os_instance()) {
			notify($ERRORS{'CRITICAL'}, 0, "failed to delete VM $computer_name on VM host $vmhost_name");
		}
	}
	# Remove existing openstack id for computer mapping in database 
	# Althought the instance is not pingable (delete it accidently), it should delete the instance from database
	if (!$self->_delete_os_computer_mapping()) {
		notify($ERRORS{'WARNING'}, 0, "failed to delete the openstack instance id from openstackcomputermap");
		return;
	}

	# Create new instance 
	my $os_instance_id = $self->_post_os_create_instance();
	if (!defined($os_instance_id)) {
		notify($ERRORS{'CRITICAL'}, 0, "failed to create an instance for computer $computer_name on VM host: $vmhost_name");
		return;
	}

	# Update the private ip of the instance in database
	if (!$self->_update_private_ip($os_instance_id)) {
		notify($ERRORS{'WARNING'}, 0, "failed to update private ip of the instance in database");
		return;
	}

	# Call post_load 
	if ($self->os->can("post_load")) {
		notify($ERRORS{'DEBUG'}, 0, "calling " . ref($self->os) . "->post_load()");
		if ($self->os->post_load()) {
			notify($ERRORS{'DEBUG'}, 0, "successfully ran OS post_load subroutine");
		}
		else {
			notify($ERRORS{'WARNING'}, 0, "failed to run OS post_load subroutine");
			return;
		}
	}
	else {
		notify($ERRORS{'WARNING'}, 0, ref($self->os) . "::post_load() has not been implemented");
		return;
	}

	return 1;

} ## end sub load

#//////////////////////////////////////////////////////////////////////////////

=head2 capture

 Parameters  : None
 Returns     : 1 if sucessful, 0 if failed
 Description : capturing a new OpenStack image.

=cut

sub capture {
	my $self = shift;

	if (ref($self) !~ /openstack/i) {
		notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a function, it must be called as a class method");
		return;
	}

	my $reservation_id = $self->data->get_reservation_id() || return;
	my $current_imagerevision_id = $self->os->get_current_imagerevision_id();
	my $computer_id = $self->data->get_computer_id() || return;
	my $image_name = $self->data->get_image_name() || return;
	my $computer_name = $self->data->get_computer_short_name() || return;
	my $computer_private_ip_address = $self->data->get_computer_private_ip_address() || return;

	insertloadlog($reservation_id, $computer_id, "startcapture", "$computer_name $image_name");
	notify($ERRORS{'DEBUG'}, 0, "computer_private_ip_address = [$computer_private_ip_address]");
	
	# Remove existing VMs which were created for the reservation computer
	if (!_pingnode($computer_private_ip_address)) {
		notify($ERRORS{'WARNING'}, 0, "unable to ping to $computer_name");
		return;
	}

	my $os_instance_id = $self->_get_os_instance_id();
	if (!defined($os_instance_id)) {
		notify($ERRORS{'WARNING'}, 0, "unable to get instance id for $computer_name");
		return;
	}
	notify($ERRORS{'DEBUG'}, 0, "os_instance_id: $os_instance_id");

	my $os_flavor_id = _get_os_flavor_id($current_imagerevision_id);
	notify($ERRORS{'DEBUG'}, 0, "current imagerevision id is $current_imagerevision_id, flavor_id: $os_flavor_id");
	if (!defined($os_flavor_id)) {
		notify($ERRORS{'WARNING'}, 0, "failed to get current openstack flavor id");
		return;
	}
		
	if (!$self->_prepare_capture()) {
		notify($ERRORS{'WARNING'}, 0, "failed to execute prepare_capture");
		return;
	}
	
	my $os_image_id = $self->_post_os_create_image($os_instance_id);
	if (!defined($os_image_id)) {
		notify($ERRORS{'CRITICAL'}, 0, "failed to create image for $computer_name");
		return;
	}
	notify($ERRORS{'DEBUG'}, 0, "os_image_id: $os_image_id");

	if (!$self->_wait_for_copying_image($os_image_id)) {
		notify($ERRORS{'WARNING'}, 0, "failed to execute _wait_for_copying_image for $os_image_id");
		return;
	}

	# insert image details and flavor details, check status is ACTIVE before insert
	if (!$self->_insert_os_image_id($os_image_id, $os_flavor_id)) {
		notify($ERRORS{'WARNING'}, 0, "failed to insert openstack image id");
		return;
	}
	notify($ERRORS{'DEBUG'}, 0, "capturing $os_instance_id into $os_image_id is done");

	return 1;
} ## end sub capture

#//////////////////////////////////////////////////////////////////////////////

=head2 does_image_exist

 Parameters  : 
 Returns     : 1 or 0
 Description : Checks the existence of an image.

=cut

sub does_image_exist {
	my $self = shift;
	if (ref($self) !~ /openstack/i) {
		notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a function, it must be called as a class method");
		return 0;
	}

	my $imagerevision_id = $self->data->get_imagerevision_id() || return 0;
	my $image_name = $self->data->get_image_name() || return 0;
	my ($os_token, $os_compute_url) = $self->_get_os_token_compute_url();
	my $os_project_id = $ENV->{'OS_PROJECT_ID'};
	if (!defined($os_token) || !defined($os_compute_url) || !defined($os_project_id)) {
		notify($ERRORS{'WARNING'}, 0, "failed to get openstack auth info");
		return 0;
	}

	# Get the openstack image id for the corresponding VCL image revision id
	my $os_image_id = _get_os_image_id($imagerevision_id);
	if (!defined($os_image_id)) {
		notify($ERRORS{'WARNING'}, 0, "failed to acquire the openstack image id : $os_image_id");
		return 0;
	}

	my $ua = LWP::UserAgent->new();
	my $resp = $ua->get(
		$os_compute_url . "/images/" . $os_image_id,
		x_auth_token => $os_token,
		x_auth_project_id => $os_project_id,
	);

	if (!$resp->is_success) {
		notify($ERRORS{'WARNING'}, 0, "failed to execute post token: " . join("\n", $resp->content));
		return 0;
	}

	my $output = from_json($resp->content);
	if (!defined($output)) {
		notify($ERRORS{'WARNING'}, 0, "failed to parse json ouput: $output");
		return 0;
	}

	my $image_status = $output->{image}{status};
	if (defined($image_status) && $image_status eq 'ACTIVE') {
		notify($ERRORS{'OK'}, 0, "The openstack image for $image_name exists");
		return 1;
	}
	else {
		notify($ERRORS{'WARNING'}, 0, "The openstack image for $image_name does NOT exists");
		return 0;
	}

} ## end sub does_image_exist

#//////////////////////////////////////////////////////////////////////////////

=head2  get_image_size

 Parameters  : imagename
 Returns     : 0 failure or size of image
 Description : in size of Megabytes

=cut

sub get_image_size {
	my $self = shift;
	if (ref($self) !~ /openstack/i) {
		notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a function, it must be called as a class method");
		return;
	}
 
	# Attempt to get the image name argument
	my $image_name = shift;
	my $imagerevision_id = $self->data->get_imagerevision_id() || return;
	my ($os_token, $os_compute_url) = $self->_get_os_token_compute_url();
	my $os_project_id = $ENV->{'OS_PROJECT_ID'};
	if (!defined($os_token) || !defined($os_compute_url) || !defined($os_project_id)) {
		notify($ERRORS{'WARNING'}, 0, "failed to get openstack auth info");
		return;
	}
	my $os_image_id = _get_os_image_id($imagerevision_id);
	if (!defined($os_image_id)) {
		notify($ERRORS{'WARNING'}, 0, "failed to acquire the openstack image id : $os_image_id for $image_name");
		return;
	}

	my $ua = LWP::UserAgent->new();
	my $resp = $ua->get(
		$os_compute_url . "/images/" . $os_image_id,
		x_auth_token => $os_token,
		x_auth_project_id => $os_project_id,
	);

	if (!$resp->is_success) {
		notify($ERRORS{'WARNING'}, 0, "failed to execute post token: " . join("\n", $resp->content));
		return;
	}

	my $output = from_json($resp->content);
	if (!defined($output)) {
		notify($ERRORS{'WARNING'}, 0, "failed to parse json ouput: $output");
		return;
	}

	my $os_image_size_bytes = $output->{'image'}{'OS-EXT-IMG-SIZE:size'};
	if (!defined($os_image_size_bytes)) {
		notify($ERRORS{'WARNING'}, 0, "The openstack image size for $image_name does NOT exists");
		return;
	}

	notify($ERRORS{'DEBUG'}, 0, "os_image_size_bytes: $os_image_size_bytes for $image_name");
	return round($os_image_size_bytes / 1024 / 1024);
} ## end sub get_image_size

#//////////////////////////////////////////////////////////////////////////////

=head2 node_status

 Parameters  : $computer_id or $hash->{computer}{id} (optional)
 Returns     : string -- 'READY', 'POST_LOAD', or 'RELOAD'
 Description : Checks the status of a VM. 'READY' is returned if the VM is
	       accessible via SSH, and the OS module's post-load tasks have
	       run. 'POST_LOAD' is returned if the VM only needs to have
	       the OS module's post-load tasks run before it is ready.
	       'RELOAD' is returned otherwise.

=cut

sub node_status {
	my $self;

	# Get the argument
	my $argument = shift;

	# Check if this subroutine was called an an object method or an argument was passed
	if (ref($argument) =~ /VCL::Module/i) {
		$self = $argument;
	}
	elsif (!ref($argument) || ref($argument) eq 'HASH') {
		# An argument was passed, check its type and determine the computer ID
		my $computer_id;
		if (ref($argument)) {
			# Hash reference was passed
			$computer_id = $argument->{id};
		}
		elsif ($argument =~ /^\d+$/) {
			# Computer ID was passed
			$computer_id = $argument;
		}
		else {
			# Computer name was passed
			($computer_id) = get_computer_ids($argument);
		}

		if ($computer_id) {
			notify($ERRORS{'DEBUG'}, 0, "computer ID: $computer_id");
		}

		else {
			notify($ERRORS{'WARNING'}, 0, "unable to determine computer ID from argument:\n" . format_data($argument));
			return;
		}

		# Create a DataStructure object containing data for the computer specified as the argument
		my $data;
		eval {
			$data= new VCL::DataStructure({computer_identifier => $computer_id});
		};
		if ($EVAL_ERROR) {
			notify($ERRORS{'WARNING'}, 0, "failed to create DataStructure object for computer ID: $computer_id, error: $EVAL_ERROR");
			return;
		}
		elsif (!$data) {
			notify($ERRORS{'WARNING'}, 0, "failed to create DataStructure object for computer ID: $computer_id, DataStructure object is not defined");
			return;
		}
		else {
			notify($ERRORS{'DEBUG'}, 0, "created DataStructure object  for computer ID: $computer_id");
		}

		# Create a VMware object
		my $object_type = 'VCL::Module::Provisioning::openstack';
		if ($self = ($object_type)->new({data_structure => $data})) {
			notify($ERRORS{'DEBUG'}, 0, "created $object_type object to check the status of computer ID: $computer_id");
		}
		else {
			notify($ERRORS{'WARNING'}, 0, "failed to create $object_type object to check the status of computer ID: $computer_id");
			return;
		}

		# Create an OS object for the VMware object to access
		if (!$self->create_os_object()) {
			notify($ERRORS{'WARNING'}, 0, "failed to create OS object");
			return;
		}
	}

	my $reservation_id = $self->data->get_reservation_id();
	my $computer_name = $self->data->get_computer_node_name();
	my $image_name = $self->data->get_image_name();
	my $request_forimaging = $self->data->get_request_forimaging();
	my $imagerevision_id = $self->data->get_imagerevision_id();
	my $computer_private_ip_address = $self->data->get_computer_private_ip_address();


	notify($ERRORS{'DEBUG'}, 0, "attempting to check the status of computer $computer_name, image: $image_name");

	# Create a hash reference and populate it with the default values
	my $status;
	$status->{currentimage} = '';
	$status->{ssh} = 0;
	$status->{image_match} = 0;
	$status->{status} = 'RELOAD';

	# Check if node is pingable and retrieve the power status if the reservation ID is 0
	# The reservation ID will be 0 is this subroutine was not called as an object method, but with a computer ID argument
	# The reservation ID will be 0 when called from healthcheck.pm
	# The reservation ID will be > 0 if called from a normal VCL reservation
	# Skip the ping and power status checks for a normal reservation to speed things up
	if (!$reservation_id) {
		if (_pingnode($computer_private_ip_address)) {
			notify($ERRORS{'DEBUG'}, 0, "VM $computer_name is pingable");
			$status->{ping} = 1;
		}
		else {
			notify($ERRORS{'DEBUG'}, 0, "VM $computer_name is not pingable");
			$status->{ping} = 0;
		}

	}

	notify($ERRORS{'DEBUG'}, 0, "Trying to ssh...");
	# Check if SSH is available
	if ($self->os->is_ssh_responding()) {
		notify($ERRORS{'DEBUG'}, 0, "VM $computer_name is responding to SSH");
		$status->{ssh} = 1;
	}
	else {
		notify($ERRORS{'OK'}, 0, "VM $computer_name is not responding to SSH, returning 'RELOAD'");
		$status->{status} = 'RELOAD';
		$status->{ssh} = 0;

		# Skip remaining checks if SSH isn't available
		return $status;
	}

	my $current_image_revision_id = $self->os->get_current_imagerevision_id();
	$status->{currentimagerevision_id} = $current_image_revision_id;

	$status->{currentimage} = $self->data->get_computer_currentimage_name();
	my $current_image_name = $status->{currentimage};
	my $vcld_post_load_status = $self->os->get_post_load_status();

	if (!$current_image_revision_id) {
		notify($ERRORS{'OK'}, 0, "unable to retrieve image name from currentimage.txt on VM $computer_name, returning 'RELOAD'");
		return $status;
	}
	elsif ($current_image_revision_id eq $imagerevision_id) {
		notify($ERRORS{'OK'}, 0, "currentimage.txt image $current_image_revision_id ($current_image_name) matches requested imagerevision_id $imagerevision_id  on VM $computer_name");
		$status->{image_match} = 1;
	}
	else {
		notify($ERRORS{'OK'}, 0, "currentimage.txt imagerevision_id $current_image_revision_id ($current_image_name) does not match requested imagerevision_id $imagerevision_id on VM $computer_name, returning 'RELOAD'");
		return $status;
	}


	# Determine the overall machine status based on the individual status results
	if ($status->{ssh} && $status->{image_match}) {
		$status->{status} = 'READY';
	}
	else {
		$status->{status} = 'RELOAD';
	}

	notify($ERRORS{'DEBUG'}, 0, "status set to $status->{status}");


	if ($request_forimaging) {
		$status->{status} = 'RELOAD';
		notify($ERRORS{'OK'}, 0, "request_forimaging set, setting status to RELOAD");
	}

	if ($vcld_post_load_status) {
		notify($ERRORS{'DEBUG'}, 0, "OS module post_load tasks have been completed on VM $computer_name");
		$status->{status} = 'READY';
	}
	else {
		notify($ERRORS{'OK'}, 0, "OS module post_load tasks have not been completed on VM $computer_name, returning 'POST_LOAD'");
		$status->{status} = 'POST_LOAD';
	}

	notify($ERRORS{'DEBUG'}, 0, "returning node status hash reference (\$node_status->{status}=$status->{status})");
	return $status;

} ## end sub node_status

											       
#//////////////////////////////////////////////////////////////////////////////

=head2 _delete_os_computer_mapping

 Parameters  : computer id
 Returns     : 1 or 0
 Description : delete match VCL computer id with OpenStack instance id

=cut

sub _delete_os_computer_mapping {
	my $self = shift;
	my $computer_id = $self->data->get_computer_id();
	if (!defined($computer_id)) {
		notify($ERRORS{'WARNING'}, 0, "failed to get computer id");
		return 0;
	}

	my $sql_statement = <<EOF;
SELECT
computerid
FROM
openstackcomputermap
WHERE
computerid = '$computer_id'
EOF

	#notify($ERRORS{'DEBUG'}, 0, "delete_os_computer_mapping: $sql_statement");
	my @selected_rows = database_select($sql_statement);
	if (scalar @selected_rows == 0) {
		notify($ERRORS{'OK'}, 0, "no instance for $computer_id");
		return 1;
	}

	$sql_statement = <<EOF;
DELETE FROM
openstackcomputermap
WHERE
computerid = '$computer_id'
EOF
	#notify($ERRORS{'DEBUG'}, 0, "$sql_statement");
	my $result = database_execute($sql_statement);

	if (!defined($result)) {
		notify($ERRORS{'WARNING'}, 0, "failed to delete computer mapping");
		return 0;
	}

	notify($ERRORS{'DEBUG'}, 0, "successfully deleted computer mapping");
	sleep 5;
	return 1;
} ## end sub _delete_os_computer_mapping

#//////////////////////////////////////////////////////////////////////////////

=head2 _get_os_flavor_id

 Parameters  : image revision id 
 Returns     : OpenStack image id or 0
 Description : match VCL image revision id with OpenStack image id 

=cut

sub _get_os_flavor_id {
	my $imagerevision_id = shift;
	if (!defined($imagerevision_id)) {
		notify($ERRORS{'WARNING'}, 0, "failed to get image revision id");
		return;
	}

	my $sql_statement = <<EOF;
SELECT
flavordetails as flavor
FROM
openstackimagerevision 
WHERE
imagerevisionid = '$imagerevision_id'
EOF

	#notify($ERRORS{'DEBUG'}, 0, "get_os_flavor_id: $sql_statement");
	my @selected_rows = database_select($sql_statement);
	if (scalar @selected_rows == 0 || scalar @selected_rows > 1) {
		notify($ERRORS{'WARNING'}, 0, "" . scalar @selected_rows . " rows were returned from database select");
		return;
	}
	my $os_flavor_detail  = from_json($selected_rows[0]{flavor});
	if (!defined($os_flavor_detail)) {
		notify($ERRORS{'WARNING'}, 0, "failed to get openstack flavor detail");
		return;
	}
	my $os_flavor_id = $os_flavor_detail->{flavor}{id};
	if (!defined($os_flavor_id)) {
		notify($ERRORS{'WARNING'}, 0, "failed to get openstack flavor id");
		return;
	}

	notify($ERRORS{'DEBUG'}, 0, "os_flavor_id: $os_flavor_id");
	return $os_flavor_id;
} ## end sub _get_os_flavor_id

#//////////////////////////////////////////////////////////////////////////////

=head2 _get_os_image_id

 Parameters  : image revision id 
 Returns     : OpenStack image id or 0
 Description : Get the OpenStack image id corresponding to the VCL image revision id  

=cut

sub _get_os_image_id {
	my $imagerevision_id = shift;
	if (!defined($imagerevision_id)) {
		notify($ERRORS{'DEBUG'}, 0, "failed to get image revision id");
		return 0;
	}

	my $sql_statement = <<EOF;
SELECT
imagedetails as image
FROM
openstackimagerevision 
WHERE
imagerevisionid = '$imagerevision_id'
EOF

	notify($ERRORS{'DEBUG'}, 0, "get_os_image_id: $sql_statement");
	my @selected_rows = database_select($sql_statement);
	if (scalar @selected_rows == 0 || scalar @selected_rows > 1) {
		notify($ERRORS{'WARNING'}, 0, "" . scalar @selected_rows . " rows were returned from database select");
		return 0;
	}
	my $os_image_detail = from_json($selected_rows[0]{image});
	if (!defined($os_image_detail)) {
		notify($ERRORS{'WARNING'}, 0, "failed to get openstack image detail");
		return 0;
	}

	my $os_image_id = $os_image_detail->{image}{id};
	if (!defined($os_image_id)) {
		notify($ERRORS{'WARNING'}, 0, "failed to get openstack image id");
		return 0;
	}

	notify($ERRORS{'DEBUG'}, 0, "openstack image_id: $os_image_id");

	return $os_image_id;
} ## end sub _get_os_image_id

#//////////////////////////////////////////////////////////////////////////////

=head2 _get_os_instance_id

 Parameters  : None
 Returns     : OpenStack instance id or 0
 Description : Checks the existence of an OpenStack instance.

=cut
sub _get_os_instance_id {
	my $self = shift;
	my $computer_id = $self->data->get_computer_id();
	if (!defined($computer_id)) {
		notify($ERRORS{'WARNING'}, 0, "failed to get computer id");
		return;
	}

	my $sql_statement = <<EOF;
SELECT
instanceid as id
FROM
openstackcomputermap
WHERE
computerid = '$computer_id'
EOF

	#notify($ERRORS{'DEBUG'}, 0, "$sql_statement");
	my @selected_rows = database_select($sql_statement);
	if (scalar @selected_rows == 0 || scalar @selected_rows > 1) {
		notify($ERRORS{'WARNING'}, 0, "" . scalar @selected_rows . " rows were returned from database select");
		return;
	}

	my $os_instance_id = $selected_rows[0]{id};
	if (!defined($os_instance_id)) {
		notify($ERRORS{'WARNING'}, 0, "failed to get openstack instance id");
		return;
	}

	notify($ERRORS{'DEBUG'}, 0, "Openstack instance id for $computer_id is $os_instance_id");
	return $os_instance_id;
}

#//////////////////////////////////////////////////////////////////////////////

=head2 _get_os_token_computer_url

 Parameters  : None 
 Returns     : Openstack auth (token, compute url) or 0
 Description : Get the OpenStack auth token and compute url   

=cut

sub _get_os_token_compute_url {
	my $self = shift;

	my $os_auth_url = $ENV->{'OS_AUTH_URL'};
	my $os_tenant_name = $ENV->{'OS_TENANT_NAME'};
	my $os_user_name = $ENV->{'OS_USERNAME'};
	my $os_user_password = $ENV->{'OS_PASSWORD'};
	my $os_service_name = $ENV->{'OS_SERVICE_NAME'};
	if (!defined($os_auth_url) || !defined($os_tenant_name) 
		|| !defined($os_user_name) || !defined($os_user_password) || !defined($os_service_name)) {
		notify($ERRORS{'WARNING'}, 0, "failed to get openstack auth information from environment");
		return 0;
	}

	my $os_auth_data = {
		auth =>  {
			tenantName => $os_tenant_name,
			passwordCredentials => {
				username => $os_user_name,
				password => $os_user_password,
			}
		}
	};

	my $ua = LWP::UserAgent->new();
	my $resp =  $ua->post(
		$os_auth_url . "/tokens",
		content_type => 'application/json', 
		content => to_json($os_auth_data)
	);
	if (!$resp->is_success) {
		notify($ERRORS{'WARNING'}, 0, "failed to get openstack token: " . join("\n", $resp->content));
		return 0;
	}
	
	my $output = from_json($resp->content);
	if (!defined($output)) {
		notify($ERRORS{'WARNING'}, 0, "failed to parse json output");
		return 0;
	}

	my $os_token = $output->{access}{token}{id};
	if (!defined($os_token)) {
		notify($ERRORS{'WARNING'}, 0, "failed to get token");
		return 0;
	}

	my @serviceCatalog = @{ $output->{access}{serviceCatalog} };
	@serviceCatalog = grep { $_->{type} eq 'compute' } @serviceCatalog;
	if (!@serviceCatalog) {
		notify($ERRORS{'WARNING'}, 0, "failed to get compute service catalog");
		return 0;
	}

	@serviceCatalog = grep { $_->{name} eq $os_service_name } @serviceCatalog;
	my $serviceCatalog = $serviceCatalog[0];
	if (!defined($serviceCatalog)) {
		notify($ERRORS{'WARNING'}, 0, "failed to get service name: $os_service_name");
		return 0;
	}

	my $os_compute_url = $serviceCatalog->{endpoints}[0]{publicURL};
	if (!defined($os_compute_url)) {
		notify($ERRORS{'WARNING'}, 0, "failed to get compute server url");
		return 0;
	}

	#notify($ERRORS{'DEBUG'}, 0, "token: $os_token, compute_url: $os_compute_url");
	return ($os_token, $os_compute_url);
} ## end sub get_os_token_compute_url

#//////////////////////////////////////////////////////////////////////////////

=head2 _insert_os_image_id

 Parameters  : OpenStack image id
 Returns     : 1 or 0
 Description : insert OpenStack image id and corresponding imagerevision id     

=cut

sub _insert_os_image_id {
	my $self = shift;
	my ($os_image_id, $os_flavor_id) = @_;
	notify($ERRORS{'DEBUG'}, 0, "the openstack id: $os_image_id,  flavor id: $os_flavor_id");
	if (!defined($os_image_id) || !defined($os_flavor_id)) {
		notify($ERRORS{'WARNING'}, 0, "failed to get the openstack id: $os_image_id or flavor id: $os_flavor_id");
		return 0;
	}
	my $imagerevision_id = $self->data->get_imagerevision_id();
	if (!defined($imagerevision_id)) {
		notify($ERRORS{'WARNING'}, 0, "failed to get the imagerevision id");
		return 0;
	}
	my ($os_token, $os_compute_url) = $self->_get_os_token_compute_url();
	my $os_project_id = $ENV->{'OS_PROJECT_ID'};
	if (!defined($os_token) || !defined($os_compute_url) || !defined($os_project_id)) {
		notify($ERRORS{'WARNING'}, 0, "failed to get the openstack auth info");
		return 0;
	}

	my $ua = LWP::UserAgent->new();
	my $res = $ua->get(
		$os_compute_url . "/images/" . $os_image_id,
		x_auth_token => $os_token,
		x_auth_project_id => $os_project_id,
	);
	if (!$res->is_success) {
		notify($ERRORS{'WARNING'}, 0, "failed to get openstack image info: " . join("\n", $res->content));
		return 0;
	}
	my $os_image_details = $res->content;
	if (!defined($os_image_details)) {
		notify($ERRORS{'WARNING'}, 0, "failed to parse json output");
		return 0;
	}

	my $resp = $ua->get(
		$os_compute_url . "/flavors/". $os_flavor_id,
		x_auth_token => $os_token,
		x_auth_project_id => $os_project_id,
	);
	if (!$resp->is_success) {
		notify($ERRORS{'WARNING'}, 0, "failed to get openstack flavor info: " . join("\n", $resp->content));
		return 0;
	}
	my $os_flavor_details = $resp->content;
	if (!defined($os_flavor_details)) {
		notify($ERRORS{'WARNING'}, 0, "failed to parse json output");
		return 0;
	}

	my $sql_statement = <<EOF;
INSERT INTO
openstackimagerevision (
imagerevisionid, 
imagedetails,
flavordetails) 
VALUES ( 
	'$imagerevision_id',
	'$os_image_details',
	'$os_flavor_details')
EOF

	#notify($ERRORS{'DEBUG'}, 0, "$sql_statement");
	my $result = database_execute($sql_statement);

	if (!defined($result)) {
		notify($ERRORS{'WARNING'}, 0, "failed to insert openstack image id");
		return 0;
	}

	notify($ERRORS{'DEBUG'}, 0, "successfully insert openstack image id");
	sleep 5;
	return 1;
} ## end sub _insert_os_image_id

#//////////////////////////////////////////////////////////////////////////////

=head2 _insert_os_instance_id

 Parameters  : OpenStack instance id
 Returns     : 1 or 0
 Description : insert OpenStack instance id and corresponding computer id

=cut

sub _insert_os_instance_id {
	my $self = shift;
	my $os_instance_id = shift;
	my $computer_id = $self->data->get_computer_id();
	if (!defined($os_instance_id) || !defined($computer_id)) {
		notify($ERRORS{'DEBUG'}, 0, "failed to get the openstack instance id: $os_instance_id or computer id: $computer_id");
		return 0;
	}

	my $sql_statement = <<EOF;
INSERT INTO
openstackcomputermap (
instanceid,
computerid)
VALUES
('$os_instance_id', '$computer_id')
EOF

	#notify($ERRORS{'DEBUG'}, 0, "$sql_statement");
	my $result = database_execute($sql_statement);
	if (!defined($result)) {
		notify($ERRORS{'WARNING'}, 0, "failed to insert openstack instance id");
		return 0;
	}

	notify($ERRORS{'DEBUG'}, 0, "successfully insert openstack instance id and comptuer id");
	sleep 5;
	return 1;
} ## end sub_insert_os_instance_id

#//////////////////////////////////////////////////////////////////////////////

=head2 _post_os_create_image

 Parameters  : OpenStack instance id
 Returns     : 1 or 0
 Description : capture OpenStack instance    

=cut

sub _post_os_create_image{
	my $self = shift;
	my $os_instance_id = shift;
	if (!defined($os_instance_id)) {
		notify($ERRORS{'WARNING'}, 0, "failed to get the openstack instance id");
		return;
	}
	notify($ERRORS{'DEBUG'}, 0, "os_instance_id: $os_instance_id in sub _post_os_create_image");
	my $image_name = $self->data->get_image_name();
	if (!defined($image_name)) {
		notify($ERRORS{'WARNING'}, 0, "failed to get openstack auth information from environment");
		return;
	}
	notify($ERRORS{'DEBUG'}, 0, "os_image_name: $image_name in sub _post_os_create_image");
	my ($os_token, $os_compute_url) = $self->_get_os_token_compute_url();
	my $os_project_id = $ENV->{'OS_PROJECT_ID'};
	if (!defined($os_token) || !defined($os_compute_url) || !defined($os_project_id)) {
		notify($ERRORS{'WARNING'}, 0, "failed to get openstack auth information from environment");
		return;
	}

	my $ua = LWP::UserAgent->new();
	my $server_data = {
		createImage =>  {
			name => $image_name,
		}
	};

	my $res =  $ua->post(
		$os_compute_url . "/servers/" . $os_instance_id . "/action",
		content_type => 'application/json',
		x_auth_token => $os_token,
		content => to_json($server_data)
	);

	if (!$res->is_success) {
		notify($ERRORS{'WARNING'}, 0, "failed to execute capture image: " . join("\n", $res->content));
		return;
	}

	my $resp =  $ua->get(
		$os_compute_url . "/images/detail", 
		server => $os_instance_id,
		content_type => 'application/json',
		x_auth_project_id => $os_project_id,
		x_auth_token => $os_token
	);

	if (!$resp->is_success) {
		notify($ERRORS{'WARNING'}, 0, "failed to get image info: " . join("\n", $resp->content));
		return;
	}

	my $output = from_json($resp->content);
	if (!defined($output)) {
		notify($ERRORS{'WARNING'}, 0, "failed to parse json output");
		return;
	}
	my $os_image_id = $output->{images}[0]{id};
	if (!defined($os_image_id)) {
		notify($ERRORS{'WARNING'}, 0, "failed to capture instance of $os_instance_id");
		return;
	}

	notify($ERRORS{'DEBUG'}, 0, "openstack image id for caputed instance of $os_instance_id is $os_image_id");
	return $os_image_id;
} ## end sub _post_os_create_image

#//////////////////////////////////////////////////////////////////////////////

=head2 _post_os_create_instance

 Parameters  : None
 Returns     : 1 or 0
 Description : create an OpenStack instance    

=cut

sub _post_os_create_instance {
	my $self = shift;
	
	my $imagerevision_id = $self->data->get_imagerevision_id() || return;
	my $computer_name  = $self->data->get_computer_short_name() || return;
	my $image_os_type  = $self->data->get_image_os_type() || return;
	my $os_project_id = $ENV->{'OS_PROJECT_ID'};
	my $os_key_name = $ENV->{'VCL_LINUX_KEY'};
	if (!defined($os_project_id) || !defined($os_key_name)) {
		notify($ERRORS{'WARNING'}, 0, "failed to get the openstack project id or key name");
		return;
	}
	if ($image_os_type eq 'linux') {
		$os_key_name =  $ENV->{'VCL_LINUX_KEY'};
		notify($ERRORS{'OK'}, 0, "The $os_key_name is the key for Linux (default)");
	} 
	elsif ($image_os_type eq 'windows') {
		$os_key_name =  $ENV->{'VCL_WINDOWS_KEY'};
		notify($ERRORS{'OK'}, 0, "The $os_key_name is the key for Windows");
	}

	my $os_image_id = _get_os_image_id($imagerevision_id);
	if (!defined($os_image_id)) {
		notify($ERRORS{'WARNING'}, 0, "failed to get the openstack image id");
		return;
	}

	my $os_flavor_id = _get_os_flavor_id($imagerevision_id);
	if (!$os_flavor_id) {
		notify($ERRORS{'WARNING'}, 0, "failed to get the openstack flavor id");
		return;
	}

	my $ua = LWP::UserAgent->new();
	my ($os_token, $os_compute_url) = $self->_get_os_token_compute_url();
	my $server_data = {
		server =>  {
			name => $computer_name,
			imageRef => $os_image_id,
			key_name => $os_key_name,
			flavorRef => $os_flavor_id
		}
	};

	my $resp =  $ua->post(
		$os_compute_url . "/servers",
		content_type => 'application/json',
		x_auth_token => $os_token,
		x_auth_project_id => $os_project_id,
		content => to_json($server_data)
	);

	if (!$resp->is_success) {
		notify($ERRORS{'WARNING'}, 0, "failed to execute run instance: " . join("\n", $resp->content));
		return;
	}

	my $output = from_json($resp->content);
	notify($ERRORS{'DEBUG'}, 0, "create_instance output: $output");
	if (!defined($output)) {
		notify($ERRORS{'WARNING'}, 0, "failed to parse json output");
		return;
	}
	my $os_instance_id = $output->{'server'}{'id'};
	if (!defined($os_instance_id)) {
		notify($ERRORS{'WARNING'}, 0, "failed to execute command to get the instance id on $computer_name");
		return;
	}

	if (!$self->_insert_os_instance_id($os_instance_id)) {
		notify($ERRORS{'WARNING'}, 0, "failed to insert the instance id : $os_instance_id");
		return; 
	}

	notify($ERRORS{'DEBUG'}, 0, "The create_instance: $os_instance_id\n");
	return $os_instance_id;
} ## end sub _post_os_create_instance

#//////////////////////////////////////////////////////////////////////////////

=head2 _prepare_capture

 Parameters  : None
 Returns     : 1 or 0
 Description : prepare capturing instance     

=cut

sub _prepare_capture {
	my $self = shift;
	
	my ($package, $filename, $line, $sub) = caller(0);
	my $request_data = $self->data->get_request_data();
	if (!$request_data) {
		notify($ERRORS{'WARNING'}, 0, "unable to retrieve request data hash");
		return 0;
	}
	my $computer_name = $self->data->get_computer_short_name();
	if (!defined($computer_name)) {
		notify($ERRORS{'WARNING'}, 0, "failed to get computer name");
		return 0;
	}

	if (!$self->data->set_imagemeta_sysprep(0)) {
		notify($ERRORS{'WARNING'}, 0, "failed to set the imagemeta Sysprep value to 0");
		return 0;
	}

	if ($self->os->can("pre_capture")) {
		notify($ERRORS{'OK'}, 0, "calling OS module's pre_capture() subroutine");

		if (!$self->os->pre_capture({end_state => 'on'})) {
			notify($ERRORS{'WARNING'}, 0, "OS module pre_capture() failed");
			return 0;
		}
	}

	notify($ERRORS{'DEBUG'}, 0, "pre_capture() is done");
	return 1;
} ## end sub _prepare_capture

#//////////////////////////////////////////////////////////////////////////////

=head2 _set_os_auth_conf 

 Parameters  : None 
 Returns     : 1(success) or 0(failure)
 Description : load openstack environment profile and set global environemnt variables 

example: openstack.conf
"os_tenant_name" => "admin",
"os_username" => "admin",
"os_password" => "adminpassword",
"os_auth_url" => "http://openstack_nova_url:5000/v2.0",
"os_service_name" => "nova",
"vcl_windows_key" => "vcl_windows_key",
"vcl_linux_key" => "vcl_linux_key",

=cut

sub _set_os_auth_conf {
	my $self = shift;
	# User's environment file
	my $user_config_file = '/etc/vcl/openstack/openstack.conf';
	my %config = do($user_config_file);
	if (!%config) {
		notify($ERRORS{'WARNING'},0, "failure to process $user_config_file");
		return;
	}
	$self->{config} = \%config;
	my $os_auth_url = $self->{config}->{os_auth_url};
	my $os_service_name = $self->{config}->{os_service_name};
	my $os_project_id = $self->{config}->{os_project_id};
	my $os_tenant_name = $self->{config}->{os_tenant_name};
	my $os_username = $self->{config}->{os_username};
	my $os_password = $self->{config}->{os_password};
	my $vcl_windows_key = $self->{config}->{vcl_windows_key};
	my $vcl_linux_key = $self->{config}->{vcl_linux_key};

	# Set Environment File
	$ENV->{'OS_AUTH_URL'} = $os_auth_url;
	$ENV->{'OS_SERVICE_NAME'} = $os_service_name;
	$ENV->{'OS_PROJECT_ID'} = $os_project_id;
	$ENV->{'OS_TENANT_NAME'} = $os_tenant_name;
	$ENV->{'OS_USERNAME'} = $os_username;
	$ENV->{'OS_PASSWORD'} = $os_password;
	$ENV->{'VCL_WINDOWS_KEY'} = $vcl_windows_key;
	$ENV->{'VCL_LINUX_KEY'} = $vcl_linux_key;

	return 1;
}# end sub _set_os_auth_conf

#//////////////////////////////////////////////////////////////////////////////

=head2 _terminate_os_instance

 Parameters  : None
 Returns     : 1 or 0
 Description : terminate an OpenStack instance    

=cut

sub _terminate_os_instance {
	my $self = shift;

	my $computer_name = $self->data->get_computer_short_name() || return 0;
		
	my ($os_token, $os_compute_url) = $self->_get_os_token_compute_url();
	my $os_project_id = $ENV->{'OS_PROJECT_ID'};
	my $os_instance_id = $self->_get_os_instance_id();
	if (!defined($os_token) || !defined($os_compute_url) || !defined($os_project_id) || !defined($os_instance_id)) {
		notify($ERRORS{'WARNING'}, 0, "failed to get the openstack auth info");
		return 0;
	}

	my $ua = LWP::UserAgent->new();
	my $resp =  $ua->delete(
		$os_compute_url . "/servers/" . $os_instance_id,
		x_auth_token => $os_token
	);
	if (!$resp->is_success) {
		notify($ERRORS{'WARNING'}, 0, "failed to execute terminate instance: " . join("\n", $resp->content));
		return 0;
	}

	sleep 30;
	return 1;
} ## end sub _terminate_os_instance

#//////////////////////////////////////////////////////////////////////////////

=head2 _update_os_instance

 Parameters  : OpenStack instance id
 Returns     : 1 or 0
 Description : update the private ip address of the OpenStack instance in database 

=cut

sub _update_private_ip {
	my $self = shift;
	
	my $os_instance_id = shift;
	my $computer_id = $self->data->get_computer_id() || return 0;
	my $computer_name  = $self->data->get_computer_short_name() || return 0;
	my ($os_token, $os_compute_url) = $self->_get_os_token_compute_url();
	if (!defined($os_instance_id) || !defined($os_token) || !defined($os_compute_url)) {
		notify($ERRORS{'WARNING'}, 0, "failed to get the openstack auth info");
		return 0;
	}
	my $ua = LWP::UserAgent->new();
	my ($private_ip, $output, $resp);
	my $main_loop = 60;

	# Find the correct instance among running instances using the private IP
	while ($main_loop > 0) {
		notify($ERRORS{'DEBUG'}, 0, "try to fetch the private IP address for $computer_name, loop of $main_loop");	
		$resp =  $ua->get(
			$os_compute_url . "/servers/" . $os_instance_id,
			x_auth_token => $os_token
		);
		if (!$resp->is_success) {
			notify($ERRORS{'WARNING'}, 0, "failed to execute instance detail: " . join("\n", $resp->content));
			return 0;
		}

		$output = from_json($resp->content);
		if (!defined($output)) {
			notify($ERRORS{'WARNING'}, 0, "failed to parse json output");
			return 0;
		}
		$private_ip = $output->{'server'}{'addresses'}{'private'}[0]->{'addr'};

		if (defined($private_ip)) {
			my $result = update_computer_private_ip_address($computer_id, $private_ip);
			if (!defined($result)) {
				notify($ERRORS{'WARNING'}, 0, "The $private_ip on Computer $computer_name is NOT updated");
				return 0;
			}
			notify($ERRORS{'DEBUG'}, 0, "private IP address is $private_ip for $computer_name");
			sleep 10;
			return 1;
		}
		else {
			notify($ERRORS{'DEBUG'}, 0, "waiting for assinging private IP address to $computer_name");
		}
		
		sleep 20;
		$main_loop--;
	}

	notify($ERRORS{'DEBUG'}, 0, "private IP address for $computer_name is not determined");
	return 0;
} ## end sub _update_private_ip

#//////////////////////////////////////////////////////////////////////////////

=head2 _wait_for_copying_image

 Parameters  : OpenStack image id
 Returns     : 1 or 0
 Description : wait for copying the OpenStack image to repository

=cut

sub _wait_for_copying_image {
	my $self = shift;
	
	my $os_image_id = shift;
	my ($os_token, $os_compute_url) = $self->_get_os_token_compute_url();
	my $os_project_id = $ENV->{'OS_PROJECT_ID'};
	if (!defined($os_image_id) || !defined($os_token) || !defined($os_compute_url) || !defined($os_project_id)) {
		notify($ERRORS{'WARNING'}, 0, "failed to get openstack auth info or image id: $os_image_id");
		return 0;
	}
	my $ua = LWP::UserAgent->new();
	my ($resp, $output, $image_status);

	my $main_loop = 100;
	while ($main_loop > 0) {
		$resp =  $ua->get(
			$os_compute_url . "/images/" . $os_image_id,
			content_type => 'application/json',
			x_auth_project_id => $os_project_id,
			x_auth_token => $os_token
		);

		if (!$resp->is_success) {
			notify($ERRORS{'WARNING'}, 0, "failed to get image info: " . join("\n", $resp->content));
			return 0;
		}

		$output = from_json($resp->content);
		$image_status = $output->{'image'}{'status'};
		if (defined($image_status)) {
			notify($ERRORS{'DEBUG'}, 0, "image status: $image_status for loop #$main_loop");
			if ($image_status eq 'ACTIVE') {
				notify($ERRORS{'OK'}, 0, "$os_image_id is available now");
				return 1;
			}
			elsif ($image_status eq 'SAVING') {
				notify($ERRORS{'DEBUG'}, 0, "wait 25 seconds for capturing instance");
				sleep 25;
			}
			else {
				notify($ERRORS{'DEBUG'}, 0, "failed to capture image for $os_image_id");
				return 0;
			}
		}
		sleep 10;
		$main_loop--;
	}

	return 0;
} ## end sub _wait_for_copying_image

sub power_reset {

	return 1;

}

#//////////////////////////////////////////////////////////////////////////////
1;
__END__
