diff --git a/heartbeat/openstack-cinder-volume b/heartbeat/openstack-cinder-volume
index c0a132545..f47570b8b 100755
--- a/heartbeat/openstack-cinder-volume
+++ b/heartbeat/openstack-cinder-volume
@@ -1,235 +1,378 @@
 #!/bin/sh
 #
 #
 # OCF resource agent to attach a cinder volume to an instance.
 #
 # Copyright (c) 2018 Mathieu GRZYBEK
 # Based on code of Markus Guertler
 # All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of version 2 of the GNU General Public License as
 # published by the Free Software Foundation.
 #
 # This program is distributed in the hope that it would be useful, but
 # WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 #
 # Further, this software is distributed without any warranty that it is
 # free of the rightful claim of any third person regarding infringement
 # or the like.  Any license provided herein, whether implied or
 # otherwise, applies only to this software file.  Patent licenses, if
 # any, provided herein do not apply to combinations of this program with
 # other software, or any other product whatsoever.
 #
 # You should have received a copy of the GNU General Public License
 # along with this program; if not, write the Free Software Foundation,
 # Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
 #
 
-
 #######################################################################
 # Initialization:
 
 : ${OCF_FUNCTIONS_DIR=${OCF_ROOT}/lib/heartbeat}
 . ${OCF_FUNCTIONS_DIR}/ocf-shellfuncs
 
 # Defaults
 OCF_RESKEY_openstackcli_default="/usr/bin/openstack"
+OCF_RESKEY_node_id_cache_file_default="/tmp/node_id"
+OCF_RESKEY_volume_local_check_default="true"
+
+export attached_server_id=""
 
 : ${OCF_RESKEY_openstackcli=${OCF_RESKEY_openstackcli_default}}
+: ${OCF_RESKEY_node_id_cache_file=${OCF_RESKEY_node_id_cache_file_default}}
+: ${OCF_RESKEY_volume_local_check=${OCF_RESKEY_volume_local_check_default}}
 
 #######################################################################
 
 
 USAGE="usage: $0 {start|stop|status|meta-data}";
 ###############################################################################
 
 
 ###############################################################################
 #
 # Functions
 #
 ###############################################################################
 
 
 metadata() {
 cat <<END
 <?xml version="1.0"?>
 <!DOCTYPE resource-agent SYSTEM "ra-api-1.dtd">
 <resource-agent name="openstack-cinder-volume">
 <version>2.0</version>
 <longdesc lang="en">
 Resource Agent to attach a cinder volume to an instance.
 It relies on attributes given by openstack-info resource agent (openstack_id attribute).
 </longdesc>
 <shortdesc lang="en">Attach a cinder volume</shortdesc>
 
 <parameters>
 <parameter name="openstackcli">
 <longdesc lang="en">
 Path to command line tools for openstack.
 </longdesc>
 <shortdesc lang="en">Path to Openstack CLI tool</shortdesc>
 <content type="string" default="${OCF_RESKEY_openstackcli_default}" />
 </parameter>
 
+<parameter name="node_id_cache_file">
+<longdesc lang="en">
+Path to Node ID cache file, used to avoid Openstack API calls:
+1. Is the local file written?
+2. Is openstack_id available as a node attribute?
+3. Can we get it from the API?
+</longdesc>
+<shortdesc lang="en">Path to Node ID cache file</shortdesc>
+<content type="string" default="${OCF_RESKEY_node_id_cache_file_default}" />
+</parameter>
+
+<parameter name="volume_local_check">
+<longdesc lang="en">
+This option allows the cluster to monitor the cinder volume presence without 
+calling the API.
+</longdesc>
+<shortdesc lang="en">Monitor cinder volume locally</shortdesc>
+<content type="boolean" default="${OCF_RESKEY_volume_local_check_default}" />
+</parameter>
+
 <parameter name="openrc" required="1">
 <longdesc lang="en">
 Valid Openstack credentials as openrc file from api_access/openrc.
 </longdesc>
 <shortdesc lang="en">openrc file</shortdesc>
 <content type="string" />
 </parameter>
 
 <parameter name="volume_id" required="1">
 <longdesc lang="en">
 Cinder volume identifier to use to attach the bloc storage.
 </longdesc>
 <shortdesc lang="en">Volume ID</shortdesc>
 <content type="string" />
 </parameter>
 
 </parameters>
 
 <actions>
 <action name="start" timeout="180s" />
 <action name="stop" timeout="180s" />
 <action name="monitor" depth="0" timeout="30s" interval="60s" />
 <action name="validate-all" timeout="5s" />
 <action name="meta-data" timeout="5s" />
 </actions>
 </resource-agent>
 END
 }
 
+#
+# This is used to get the node ID from different sources:
+# 1. Is the local file written?
+# 2. Is openstack_id available as a node attribute?
+# 3. Can we get it from the API?
+#
+# When the ID is retrieved, the local cache file is written.
+# This prevents the agent to call the API each time the agent is used.
+#
+_get_node_id() {
+	local crm_node
+	local node
+	local node_id
+	local result
+
+	crm_node=$(crm_node -n)
+
+	#
+	# Use local cache
+	#
+	if [ -f $OCF_RESKEY_node_id_cache_file ] ; then
+		node_id=$(cat $OCF_RESKEY_node_id_cache_file)
+		
+		if [ ! -z "$node_id" ] ; then
+			echo $node_id
+			return
+		fi
+	fi
+
+	#
+	# Query the attributes database
+	#
+	node_id=$(${HA_SBIN_DIR}/attrd_updater --query -n openstack_id -N $crm_node \
+		| tr ' ' '\n' \
+		| awk -F= '/value=/ {gsub("\"","");print $NF}')
+
+	if [ ! -z "$node_id" ] ; then
+		echo $node_id | awk '{print $1}'
+		echo $node_id | awk '{print $1}' > $OCF_RESKEY_node_id_cache_file
+		return
+	fi
+
+	#
+	# Use the API
+	#
+	node=$(crm_node -n | awk -F. '{print $1}')
+
+	result=$($OCF_RESKEY_openstackcli server list \
+		--format value --column ID --column Name \
+		| grep $node)
+
+	if [ $? -eq 0 ] ; then
+		echo $result | awk '{print $1}'
+		echo $result | awk '{print $1}' > $OCF_RESKEY_node_id_cache_file
+		return
+	fi
+
+	ocf_exit_reason "openstack_id attribute must be set for node $crm_node"
+	return $OCF_ERR_CONFIGURED
+}
+
 osvol_validate() {
+	local node_id
+
 	check_binary "$OCF_RESKEY_openstackcli"
+	check_binary "awk"
+	check_binary "tr"
+	
+	. $OCF_RESKEY_openrc
+
+	node_id=$(_get_node_id)
+
+	if [ -z "$node_id" ] ; then
+		ocf_exit_reason "openstack_id attribute must be set for node $crm_node"
+		return $OCF_ERR_CONFIGURED
+	fi
 
 	if [ -z "$OCF_RESKEY_openrc" ]; then
 		ocf_exit_reason "openrc parameter not set"
 		return $OCF_ERR_CONFIGURED
 	fi
 
 	if [ ! -f "$OCF_RESKEY_openrc" ] ; then
 		ocf_exit_reason "openrc file not found"
 		return $OCF_ERR_CONFIGURED
 	fi
 
-	. $OCF_RESKEY_openrc
-
-	if ! $OCF_RESKEY_openstackcli volume list|grep -q $OCF_RESKEY_volume_id ; then
-		ocf_exit_reason "Volume $OCF_RESKEY_volume_id not found"
-		return $OCF_ERR_CONFIGURED
-	fi
-
 	return $OCF_SUCCESS
 }
 
 osvol_monitor() {
 	local result
-	local attached_server_id
 	local node_id
+	local short_volume_id
+	local fdisk_command
+
+	if ocf_is_true $OCF_RESKEY_volume_local_check ; then
+		#
+		# Is the volue attached?
+		# We check the local devices
+		#
+		short_volume_id=$(echo $OCF_RESKEY_volume_id | awk '{print substr($0, 0, 20)}')
+		if uname | grep -q Linux ; then
+			fdisk_command="fdisk -l"
+		else
+			fdisk_command="fdisk"
+		fi
 
-	# Is the volue attached?
-	result=$($OCF_RESKEY_openstackcli volume show \
-		--column status \
-		--column attachments \
-		--format value \
-		$OCF_RESKEY_volume_id)
-
-	if [[ "$result" =~ "available" ]] ; then
-		ocf_log warn "$OCF_RESKEY_volume_id is not attached to any instance"
-		return $OCF_NOT_RUNNING
+		$fdisk_command /dev/disk/by-id/virtio-$short_volume_id 1>/dev/null 2>&1
+		if [ $? -eq 0 ] ; then
+			return $OCF_SUCCESS
+		else
+			ocf_log warn "$OCF_RESKEY_volume_id is not attached to instance $(_get_node_id)"
+			return $OCF_NOT_RUNNING
+		fi
 	else
-		attached_server_id=$(echo $result|head -n1|awk -F "'" '{print $4}')
-		ocf_log info "$OCF_RESKEY_volume_id is attached to instance $attached_server_id"
-		node_id=$(${HA_SBIN_DIR}/attrd_updater --query -n openstack_id -N $HOSTNAME \
-			| awk '{gsub("value=","") ; gsub("\"","") ; print $NF}')
-
-		if [ "$node_id" != "$attached_server_id" ] ; then
+		#
+		# Is the volue attached?
+		# We use the API
+		#
+		result=$($OCF_RESKEY_openstackcli volume show \
+			--column status \
+			--column attachments \
+			--format value \
+			$OCF_RESKEY_volume_id)
+
+		if echo "$result" | grep -q available ; then
+			ocf_log warn "$OCF_RESKEY_volume_id is not attached to any instance"
 			return $OCF_NOT_RUNNING
+		else
+			export attached_server_id=$(echo $result|head -n1|awk -F "'" '{print $4}')
+			ocf_log info "$OCF_RESKEY_volume_id is attached to instance $attached_server_id"
+
+			# Compare node_id and the id of the node the volume is attached to
+			node_id=$(_get_node_id)
+
+			if [ "$node_id" != "$attached_server_id" ] ; then
+				return $OCF_NOT_RUNNING
+			fi
 		fi
 	fi
 
 	return $OCF_SUCCESS
 }
 
 osvol_stop() {
 	local node_id
 
+	#
+	# Is the volume already attached?
+	#
 	osvol_monitor
 	if [ $? = $OCF_NOT_RUNNING ]; then
 		ocf_log info "Volume $OCF_RESKEY_volume_id already available"
 		return $OCF_SUCCESS
 	fi
 
-	node_id=$(${HA_SBIN_DIR}/attrd_updater --query -n openstack_id -N $HOSTNAME \
-		| awk '{gsub("value=","") ; gsub("\"","") ; print $NF}')
+	node_id=$(_get_node_id)
+
+	#
+	# Unmout the volume
+	#
 	if ! $OCF_RESKEY_openstackcli server remove volume $node_id $OCF_RESKEY_volume_id ; then
 		ocf_log error "Couldn't remove volume $OCF_RESKEY_volume_id from instance $node_id"
 		return $OCF_ERR_GENERIC
 	fi
 
 	ocf_log info "Successfully removed $OCF_RESKEY_volume_id from instance $node_id"
 	return $OCF_SUCCESS
 }
 
 osvol_start() {
 	local node_id
 
+	#
+	# Is the volume already attached?
+	#
 	osvol_monitor
 	if [ $? = $OCF_SUCCESS ]; then
 		ocf_log info "$OCF_RESKEY_volume_id already attached"
 		return $OCF_SUCCESS
 	fi
 
-	node_id=$(${HA_SBIN_DIR}/attrd_updater --query -n openstack_id -N $HOSTNAME \
-		| awk '{gsub("value=","") ; gsub("\"","") ; print $NF}')
+	#
+	# Unmout it from another node
+	# TODO: make it optional in case multi-attachment is allowed by Cinder
+	#
+	if [ ! -z $attached_server_id ] ; then
+		if ! $OCF_RESKEY_openstackcli server remove volume $attached_server_id $OCF_RESKEY_volume_id ; then
+			ocf_log error "Couldn't remove volume $OCF_RESKEY_volume_id from instance $attached_server_id"
+			return $OCF_ERR_GENERIC
+		fi
+	fi
+
+	export attached_server_id=""
+	
+	node_id=$(_get_node_id)
+
+	#
+	# Attach the volume
+	#
 	$OCF_RESKEY_openstackcli server add volume $node_id $OCF_RESKEY_volume_id
 	if [ $? != $OCF_SUCCESS ]; then
 		ocf_log error "Couldn't add volume $OCF_RESKEY_volume_id to instance $node_id"
 		return $OCF_ERR_GENERIC
 	fi
 
 	return $OCF_SUCCESS
 }
 
 ###############################################################################
 #
 # MAIN
 #
 ###############################################################################
 
 case $__OCF_ACTION in
 	meta-data)
 		metadata
 		exit $OCF_SUCCESS
 		;;
 	usage|help)
 		echo $USAGE
 		exit $OCF_SUCCESS
 		;;
 esac
 
 if ! ocf_is_root; then
 	ocf_log err "You must be root for $__OCF_ACTION operation."
 	exit $OCF_ERR_PERM
 fi
 
 osvol_validate
 
 case $__OCF_ACTION in
 	start)
 		osvol_start;;
 	stop)
 		osvol_stop;;
 	monitor|status)
 		osvol_monitor;;
 	validate-all)
 		exit $?;;
 	*)
 		echo $USAGE
 		exit $OCF_ERR_UNIMPLEMENTED
 		;;
 esac
diff --git a/heartbeat/openstack-floating-ip b/heartbeat/openstack-floating-ip
index d164c0982..f9cff8c67 100755
--- a/heartbeat/openstack-floating-ip
+++ b/heartbeat/openstack-floating-ip
@@ -1,267 +1,273 @@
 #!/bin/sh
 #
 #
 # OCF resource agent to move a floating address in an Openstack tenant.
 #
 # Copyright (c) 2018 Mathieu GRZYBEK
 # Based on code of Markus Guertler
 # All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of version 2 of the GNU General Public License as
 # published by the Free Software Foundation.
 #
 # This program is distributed in the hope that it would be useful, but
 # WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 #
 # Further, this software is distributed without any warranty that it is
 # free of the rightful claim of any third person regarding infringement
 # or the like.  Any license provided herein, whether implied or
 # otherwise, applies only to this software file.  Patent licenses, if
 # any, provided herein do not apply to combinations of this program with
 # other software, or any other product whatsoever.
 #
 # You should have received a copy of the GNU General Public License
 # along with this program; if not, write the Free Software Foundation,
 # Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
 #
 
 
 #######################################################################
 # Initialization:
 
 : ${OCF_FUNCTIONS_DIR=${OCF_ROOT}/lib/heartbeat}
 . ${OCF_FUNCTIONS_DIR}/ocf-shellfuncs
 
 # Defaults
 OCF_RESKEY_openstackcli_default="/usr/bin/openstack"
 
 : ${OCF_RESKEY_openstackcli=${OCF_RESKEY_openstackcli_default}}
 
 #######################################################################
 
 
 USAGE="usage: $0 {start|stop|status|meta-data}";
 ###############################################################################
 
 
 ###############################################################################
 #
 # Functions
 #
 ###############################################################################
 
 
 metadata() {
 cat <<END
 <?xml version="1.0"?>
 <!DOCTYPE resource-agent SYSTEM "ra-api-1.dtd">
 <resource-agent name="openstack-floating-ip">
 <version>2.0</version>
 <longdesc lang="en">
 Resource Agent to move a floating IP address from an instance to another one.
 It relies on attributes given by openstack-info resource agent (openstack_ports, openstack_id attributes).
 The attribute called "openstack_floating_ip" is updated.
 </longdesc>
 <shortdesc lang="en">Move a floating IP</shortdesc>
 
 <parameters>
 <parameter name="openstackcli">
 <longdesc lang="en">
 Path to command line tools for openstack.
 </longdesc>
 <shortdesc lang="en">Path to Openstack CLI tool</shortdesc>
 <content type="string" default="${OCF_RESKEY_openstackcli_default}" />
 </parameter>
 
 <parameter name="openrc" required="1">
 <longdesc lang="en">
 Valid Openstack credentials as openrc file from api_access/openrc.
 </longdesc>
 <shortdesc lang="en">openrc file</shortdesc>
 <content type="string" />
 </parameter>
 
 <parameter name="ip_id" required="1">
 <longdesc lang="en">
 Floating IP Identifier.
 </longdesc>
 <shortdesc lang="en">IP ID</shortdesc>
 <content type="string" />
 </parameter>
 
 <parameter name="subnet_id" required="1">
 <longdesc lang="en">
 Subnet Identifier to use to attach the address.
 </longdesc>
 <shortdesc lang="en">Subnet ID</shortdesc>
 <content type="string" />
 </parameter>
 
 </parameters>
 
 <actions>
 <action name="start" timeout="180s" />
 <action name="stop" timeout="180s" />
 <action name="monitor" depth="0" timeout="30s" interval="60s" />
 <action name="validate-all" timeout="5s" />
 <action name="meta-data" timeout="5s" />
 </actions>
 </resource-agent>
 END
 }
 
 osflip_validate() {
 	check_binary "$OCF_RESKEY_openstackcli"
 
 	if [ -z "$OCF_RESKEY_openrc" ]; then
 		ocf_exit_reason "openrc parameter not set"
 		return $OCF_ERR_CONFIGURED
 	fi
 
 	if [ ! -f "$OCF_RESKEY_openrc" ] ; then
 		ocf_exit_reason "openrc file not found"
 		return $OCF_ERR_CONFIGURED
 	fi
 
 	. $OCF_RESKEY_openrc
 
 	if ! $OCF_RESKEY_openstackcli floating ip list|grep -q $OCF_RESKEY_ip_id ; then
 		ocf_exit_reason "ip-id $OCF_RESKEY_ip_id not found"
 		return $OCF_ERR_CONFIGURED
 	fi
 
-	${HA_SBIN_DIR}/attrd_updater --query -n openstack_ports -N $HOSTNAME > /dev/null 2>&1
+	${HA_SBIN_DIR}/attrd_updater --query -n openstack_ports -N $(crm_node -n) > /dev/null 2>&1
 	if [ $? -ne 0 ] ; then
 		ocf_log warn "attr_updater failed to get openstack_ports attribute of node $OCF_RESOURCE_INSTANCE"
 		return $OCF_ERR_GENERIC
 	fi
 
 	return $OCF_SUCCESS
 }
 
 osflip_monitor() {
 	local result
 	local floating_ip
 	local node_port_ids
 	local port
 	local buffer
+	local crm_node
 
-	node_port_ids=$(${HA_SBIN_DIR}/attrd_updater --query -n openstack_ports -N $HOSTNAME \
+	crm_node=$(crm_node -n)
+	node_port_ids=$(${HA_SBIN_DIR}/attrd_updater --query -n openstack_ports -N $crm_node \
 		| awk -F= '{gsub("\"","");print $NF}' \
 		| tr ',' ' ' \
 		| awk -F: '{print $NF}')
 
 	# Is the IP active and attached?
 	result=$($OCF_RESKEY_openstackcli floating ip show \
 		--column port_id --column floating_ip_address \
 		--format yaml \
 		$OCF_RESKEY_ip_id)
 
 	for port in $node_port_ids ; do
 		if echo $result | grep -q $port ; then
 			floating_ip=$(echo $result | awk '/floating_ip_address/ {print $2}')
-			${HA_SBIN_DIR}/attrd_updater ${OCF_RESKEY_delay} -n openstack_floating_ip -v $floating_ip
+			${HA_SBIN_DIR}/attrd_updater ${OCF_RESKEY_delay} -S status -n openstack_floating_ip -v $floating_ip
 
 			return $OCF_SUCCESS
 		fi
 	done
 
-	${HA_SBIN_DIR}/attrd_updater ${OCF_RESKEY_delay} -D -n openstack_floating_ip
+	${HA_SBIN_DIR}/attrd_updater ${OCF_RESKEY_delay} -D -S state -n openstack_floating_ip
 	ocf_log warn "$OCF_RESKEY_ip_id is not attached to any fixed address"
 	return $OCF_NOT_RUNNING
 }
 
 osflip_stop() {
 	ocf_log info "Bringing down IP address $OCF_RESKEY_ip_id"
 
 	osflip_monitor
 	if [ $? = $OCF_NOT_RUNNING ]; then
 		ocf_log info "Address $OCF_RESKEY_ip_id already down"
 		return $OCF_SUCCESS
 	fi
 
 	if ! $OCF_RESKEY_openstackcli floating ip unset --port $OCF_RESKEY_ip_id ; then
 		return $OCF_ERR_GENERIC
 	fi
 
 	osflip_monitor
 	if [ $? != $OCF_NOT_RUNNING ]; then
 		ocf_log error "Couldn't unset IP address $OCF_RESKEY_ip_id."
 		return $OCF_ERR_GENERIC
 	fi
 
 	ocf_log info "Successfully brought unset $OCF_RESKEY_ip_id"
 	return $OCF_SUCCESS
 }
 
 osflip_start() {
 	local node_port_id
 	local node_port_ids
 
 	osflip_monitor
 	if [ $? = $OCF_SUCCESS ]; then
 		ocf_log info "$OCF_RESKEY_ip_id already started"
 		return $OCF_SUCCESS
 	fi
 
 	# Get port_id from subnet_id
-	node_port_ids=$(${HA_SBIN_DIR}/attrd_updater --query -n openstack_ports -N $HOSTNAME \
+	node_port_ids=$(${HA_SBIN_DIR}/attrd_updater --query -n openstack_ports -N $(crm_node -n) \
 		| awk '{gsub("value=","") ; gsub("\"","") ; print $NF}')
-	node_port_id=$(echo $node_port_ids|tr ',' '\n'|awk -F: "/$OCF_RESKEY_subnet_id/ {print \$2}")
+
+	node_port_id=$(echo $node_port_ids \
+		| tr ',' '\n' \
+		| awk -F: "/$OCF_RESKEY_subnet_id/ {print \$2}")
+
 	ocf_log info "Moving IP address $OCF_RESKEY_ip_id to port ID $node_port_id"
 
 	$OCF_RESKEY_openstackcli floating ip set --port $node_port_id $OCF_RESKEY_ip_id
 	if [ $? != $OCF_SUCCESS ]; then
 		ocf_log error "$OCF_RESKEY_ip_id Cannot be set to port $node_port_id"
 		return $OCF_ERR_GENERIC
 	fi
 
 	osflip_monitor
 	if [ $? != $OCF_SUCCESS ]; then
 		ocf_log error "$OCF_RESKEY_ip_id Cannot be set to port $node_port_id"
 		return $OCF_ERR_GENERIC
 	fi
 
 	return $OCF_SUCCESS
 }
 
 ###############################################################################
 #
 # MAIN
 #
 ###############################################################################
 
 case $__OCF_ACTION in
 	meta-data)
 		metadata
 		exit $OCF_SUCCESS
 		;;
 	usage|help)
 		echo $USAGE
 		exit $OCF_SUCCESS
 		;;
 esac
 
 if ! ocf_is_root; then
 	ocf_log err "You must be root for $__OCF_ACTION operation."
 	exit $OCF_ERR_PERM
 fi
 
 osflip_validate
 
 case $__OCF_ACTION in
 	start)
 		osflip_start;;
 	stop)
 		osflip_stop;;
 	monitor)
 		osflip_monitor;;
 	validate-all)
 		exit $?;;
 	*)
 		echo $USAGE
 		exit $OCF_ERR_UNIMPLEMENTED
 		;;
 esac
diff --git a/heartbeat/openstack-info b/heartbeat/openstack-info
index 15e9e79b6..209039928 100755
--- a/heartbeat/openstack-info
+++ b/heartbeat/openstack-info
@@ -1,242 +1,260 @@
 #!/bin/sh
 #
 #
 # OCF resource agent to set attributes from Openstack instance details.
 # It records (in the CIB) various attributes of a node
 #
 # Copyright (c) 2018 Mathieu Grzybek
 #          All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of version 2 of the GNU General Public License as
 # published by the Free Software Foundation.
 #
 # This program is distributed in the hope that it would be useful, but
 # WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 #
 # Further, this software is distributed without any warranty that it is
 # free of the rightful claim of any third person regarding infringement
 # or the like. Any license provided herein, whether implied or
 # otherwise, applies only to this software file. Patent licenses, if
 # any, provided herein do not apply to combinations of this program with
 # other software, or any other product whatsoever.
 #
 # You should have received a copy of the GNU General Public License
 # along with this program; if not, write the Free Software Foundation,
 # Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
 #
 #######################################################################
 # Initialization:
 
 : ${OCF_FUNCTIONS_DIR=${OCF_ROOT}/lib/heartbeat}
 . ${OCF_FUNCTIONS_DIR}/ocf-shellfuncs
 
 # Defaults
 OCF_RESKEY_openstackcli_default="/usr/bin/openstack"
 
 : ${OCF_RESKEY_openstackcli=${OCF_RESKEY_openstackcli_default}}
 #######################################################################
 
 meta_data() {
 	cat <<END
 <?xml version="1.0"?>
 <!DOCTYPE resource-agent SYSTEM "ra-api-1.dtd">
 <resource-agent name="openstack-info">
 <version>1.0</version>
 
 <longdesc lang="en">
 OCF resource agent to set attributes from Openstack instance details.
 It records (in the CIB) various attributes of a node.
 Sample output:
 	openstack_az      : nova
 	openstack_flavor  : c1.small
 	openstack_id      : 60ac4343-5828-49b1-8aac-7c69b1417f31
 	openstack_ports   : 7960d889-9750-4160-bf41-c69a41ad72d9:96530d18-57a3-4718-af32-30f2a74c22a2,b0e55a06-bd75-468d-8baa-22cfeb65799f:a55ae917-8016-4b1e-8ffa-04311b9dc7d6
 
 The layout of openstack_ports is a comma-separated list of tuples "subnet_id:port_id".
 </longdesc>
 <shortdesc lang="en">Records various node attributes in the CIB</shortdesc>
 
 <parameters>
 <parameter name="pidfile" unique="0">
 <longdesc lang="en">PID file</longdesc>
 <shortdesc lang="en">PID file</shortdesc>
 <content type="string" default="$OCF_RESKEY_pidfile" />
 </parameter>
 <parameter name="delay" unique="0">
 <longdesc lang="en">Interval to allow values to stabilize</longdesc>
 <shortdesc lang="en">Dampening Delay</shortdesc>
 <content type="string" default="0" />
 </parameter>
 
 <parameter name="openrc" required="1">
 <longdesc lang="en">
 Valid Openstack credentials as openrc file from api_access/openrc.
 </longdesc>
 <shortdesc lang="en">openrc file</shortdesc>
 <content type="string" />
 </parameter>
 
 <parameter name="openstackcli">
 <longdesc lang="en">
 Path to command line tools for openstack.
 </longdesc>
 <shortdesc lang="en">Path to Openstack CLI tool</shortdesc>
 <content type="string" default="${OCF_RESKEY_openstackcli_default}" />
 </parameter>
 
 </parameters>
 
 <actions>
 <action name="start"  timeout="20s" />
 <action name="stop" timeout="20s" />
 <action name="monitor" timeout="20s" interval="60s"/>
 <action name="meta-data" timeout="5s" />
 <action name="validate-all" timeout="20s" />
 </actions>
 </resource-agent>
 END
 }
 
 #######################################################################
 
 OSInfoStats() {
 	local result
 	local value
 	local node
 	local node_id
 
 	. $OCF_RESKEY_openrc
 
 	node=$(crm_node -n|awk -F. '{print $1}')
 
 	result=$($OCF_RESKEY_openstackcli server list \
 		--format value --column ID --column Name \
 		| grep $node)
 
+	if [ $? -ne 0 ] ; then
+		ocf_exit_reason "cannot find $node in instances list"
+		exit $OCF_ERR_GENERIC
+	fi
 	node_id=$(echo $result|awk '{print $1}')
 
 	# Nova data: flavor, AZ…
 	result=$($OCF_RESKEY_openstackcli server show \
 		--format value \
 		--column flavor \
 		--column OS-EXT-AZ:availability_zone \
 		$node_id | tr '\n' ' ')
 
 	${HA_SBIN_DIR}/attrd_updater ${OCF_RESKEY_delay} -n openstack_id -v $node_id
 
 	value=$(echo $result|awk '{print $2}')
 	${HA_SBIN_DIR}/attrd_updater ${OCF_RESKEY_delay} -n openstack_flavor -v $value
 
 	value=$(echo $result|awk '{print $1}')
 	${HA_SBIN_DIR}/attrd_updater ${OCF_RESKEY_delay} -n openstack_az -v $value
 
 	# Network data: ports
 	result=$($OCF_RESKEY_openstackcli port list \
 		--format value \
 		--column device_id \
 		--column id \
 		--column "Fixed IP Addresses" \
 		| awk "/^$node_id/ {gsub(\"subnet_id='\",\"\");gsub(\"'\",\"\");print \$NF\":\"\$2}" | tr '\n' ' ')
 
 	value=""
 	for p in $result ; do
 		if [ -z "$value" ] ; then
 			value="$p"
 		else
 			value="$value,$p"
 		fi
 	done
-	${HA_SBIN_DIR}/attrd_updater ${OCF_RESKEY_delay} -n openstack_ports -v $value
+	${HA_SBIN_DIR}/attrd_updater ${OCF_RESKEY_delay} -n openstack_ports -v "$value"
 
 	if [ ! -z "$OS_REGION_NAME" ] ; then
-		${HA_SBIN_DIR}/attrd_updater ${OCF_RESKEY_delay} -n openstack_region -v $OS_REGION_NAME
+		${HA_SBIN_DIR}/attrd_updater ${OCF_RESKEY_delay} -n openstack_region -v "$OS_REGION_NAME"
+	fi
+
+	if [ ! -z "$OS_TENANT_ID" ] ; then
+		${HA_SBIN_DIR}/attrd_updater ${OCF_RESKEY_delay} -n openstack_tenant_id -v "$OS_TENANT_ID"
+
+		if [ ! -z "$OS_TENANT_NAME" ] ; then
+			${HA_SBIN_DIR}/attrd_updater ${OCF_RESKEY_delay} -n openstack_tenant_name -v "$OS_TENANT_NAME"
+		fi
+	else
+		${HA_SBIN_DIR}/attrd_updater ${OCF_RESKEY_delay} -n openstack_project_id -v "$OS_PROJECT_ID"
+
+		if [ ! -z "$OS_PROJECT_NAME" ] ; then
+			${HA_SBIN_DIR}/attrd_updater ${OCF_RESKEY_delay} -n openstack_project_name -v "$OS_PROJECT_NAME"
+		fi
 	fi
 
-	${HA_SBIN_DIR}/attrd_updater ${OCF_RESKEY_delay} -n openstack_tenant_name -v $OS_TENANT_NAME
-	${HA_SBIN_DIR}/attrd_updater ${OCF_RESKEY_delay} -n openstack_tenant_id -v $OS_TENANT_ID
 }
 
 OSInfo_usage() {
 	cat <<END
 usage: $0 {start|stop|monitor|validate-all|meta-data}
 
 Expects to have a fully populated OCF RA-compliant environment set.
 END
 }
 
 OSInfo_start() {
 	echo $OCF_RESKEY_clone > $OCF_RESKEY_pidfile
 	OSInfoStats
 	exit $OCF_SUCCESS
 }
 
 OSInfo_stop() {
 	rm -f $OCF_RESKEY_pidfile
 	${HA_SBIN_DIR}/attrd_updater ${OCF_RESKEY_delay} -D -n openstack_id
 	${HA_SBIN_DIR}/attrd_updater ${OCF_RESKEY_delay} -D -n openstack_flavor
 	${HA_SBIN_DIR}/attrd_updater ${OCF_RESKEY_delay} -D -n openstack_az
 	${HA_SBIN_DIR}/attrd_updater ${OCF_RESKEY_delay} -D -n openstack_ports
 	${HA_SBIN_DIR}/attrd_updater ${OCF_RESKEY_delay} -D -n openstack_region
 	${HA_SBIN_DIR}/attrd_updater ${OCF_RESKEY_delay} -D -n openstack_tenant_id
 	${HA_SBIN_DIR}/attrd_updater ${OCF_RESKEY_delay} -D -n openstack_tenant_name
+	${HA_SBIN_DIR}/attrd_updater ${OCF_RESKEY_delay} -D -n openstack_project_id
+	${HA_SBIN_DIR}/attrd_updater ${OCF_RESKEY_delay} -D -n openstack_project_name
 	exit $OCF_SUCCESS
 }
 
 OSInfo_monitor() {
 	if [ -f "$OCF_RESKEY_pidfile" ] ; then
 		OSInfoStats
 		exit $OCF_RUNNING
 	fi
 	exit $OCF_NOT_RUNNING
 }
 
 OSInfo_validate() {
 	check_binary "$OCF_RESKEY_openstackcli"
 
 	if [ -z "$OCF_RESKEY_openrc" ]; then
 		ocf_exit_reason "openrc parameter not set"
 		return $OCF_ERR_CONFIGURED
 	fi
 
 	if [ ! -f "$OCF_RESKEY_openrc" ] ; then
 		ocf_exit_reason "openrc file not found"
 		return $OCF_ERR_CONFIGURED
 	fi
 
 	return $OCF_SUCCESS
 }
 
 if [ $# -ne 1 ]; then
 	OSInfo_usage
 	exit $OCF_ERR_ARGS
 fi
 
 : ${OCF_RESKEY_pidfile:="$HA_RSCTMP/OSInfo-${OCF_RESOURCE_HOSTNAME}"}
 : ${OCF_RESKEY_clone:="0"}
 if [ x != x${OCF_RESKEY_delay} ]; then
 	OCF_RESKEY_delay="-d ${OCF_RESKEY_delay}"
 fi
 
 case $__OCF_ACTION in
 meta-data)	meta_data
 		exit $OCF_SUCCESS
 		;;
 start)		OSInfo_start
 		;;
 stop)		OSInfo_stop
 		;;
 monitor)	OSInfo_monitor
 		;;
 validate-all)	OSInfo_validate
 		;;
 usage|help)	OSInfo_usage
 		exit $OCF_SUCCESS
 		;;
 *)		OSInfo_usage
 		exit $OCF_ERR_UNIMPLEMENTED
 		;;
 esac
 
 exit $?