#!/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 . ${OCF_FUNCTIONS_DIR}/openstack-common.sh # Defaults OCF_RESKEY_pidfile_default="$HA_RSCTMP/OSInfo-${OCF_RESOURCE_HOSTNAME}" OCF_RESKEY_delay_default="0" OCF_RESKEY_clone_default="0" OCF_RESKEY_curlcli_default="/usr/bin/curl" OCF_RESKEY_pythoncli_default="@PYTHON@" : ${OCF_RESKEY_curlcli=${OCF_RESKEY_curlcli_default}} : ${OCF_RESKEY_pythoncli=${OCF_RESKEY_pythoncli_default}} : ${OCF_RESKEY_pidfile=${OCF_RESKEY_pidfile_default}} : ${OCF_RESKEY_delay=${OCF_RESKEY_delay_default}} : ${OCF_RESKEY_clone=${OCF_RESKEY_clone_default}} ####################################################################### meta_data() { cat < 1.0 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". Records various node attributes in the CIB END common_meta_data cat < PID file PID file Interval to allow values to stabilize Dampening Delay Path to command line cURL binary. Path to cURL binary Path to command line Python interpreter. Path to Python interpreter END } ####################################################################### OSInfoStats() { local value local node_id get_config # Nova data: server ID node_id=$($OCF_RESKEY_curlcli \ -s http://169.254.169.254/openstack/latest/meta_data.json | $OCF_RESKEY_pythoncli -m json.tool | grep -P '\"uuid\": \".*\",$' | grep -P -o '[0-9a-f]{8}-([0-9a-f]{4}-){3}[0-9a-f]{12}') if [ $? -ne 0 ] ; then ocf_exit_reason "Cannot find server ID" exit $OCF_ERR_GENERIC fi ${HA_SBIN_DIR}/attrd_updater ${OCF_RESKEY_delay} -n openstack_id -v "$node_id" # Nova data: flavor value=$(run_openstackcli "server show \ --format value \ --column flavor \ $node_id") ${HA_SBIN_DIR}/attrd_updater ${OCF_RESKEY_delay} -n openstack_flavor -v "$value" # Nova data: availability zone value=$(run_openstackcli "server show \ --format value \ --column OS-EXT-AZ:availability_zone \ $node_id") ${HA_SBIN_DIR}/attrd_updater ${OCF_RESKEY_delay} -n openstack_az -v "$value" # Network data: ports value="" for port_id in $(run_openstackcli "port list \ --format value \ --column id \ --server $node_id"); do subnet_result=$(run_openstackcli "port show \ --format json \ --column fixed_ips \ ${port_id}") subnet_id=$(echo "$subnet_result" | grep -P '\"subnet_id\": \".*\",$' | grep -P -o '[0-9a-f]{8}-([0-9a-f]{4}-){3}[0-9a-f]{12}') value="${value}${subnet_id}:${port_id}," done value=${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" 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 } OSInfo_usage() { cat < $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_curlcli" check_binary "$OCF_RESKEY_openstackcli" check_binary "$OCF_RESKEY_pythoncli" return $OCF_SUCCESS } if [ $# -ne 1 ]; then OSInfo_usage exit $OCF_ERR_ARGS fi 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_validate || exit $? 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 $?