diff --git a/.gitignore b/.gitignore index ec30a3bb0..0c259b5cf 100644 --- a/.gitignore +++ b/.gitignore @@ -1,154 +1,155 @@ *.swp Makefile.in aclocal.m4 autoconf autoheader autom4te.cache automake autoscan.log compile configure configure.scan config.guess config.log config.sub config.status Makefile depcomp install-sh libtoolize ltmain.sh libtool make/stamp-h1 make/clusterautoconfig.h* missing +resource-agents.spec *.pc .deps .libs *.o *.la *.lo *.loT rgmanager/src/resources/* !rgmanager/src/resources/*.in rgmanager/src/resources/Makefile.in rgmanager/src/resources/utils/config-utils.sh resource-agents-* .version # generated by ./autogen.sh && ./configure doc/man/*.7 doc/man/*.xml heartbeat/ocf-binaries heartbeat/ocf-directories heartbeat/ocf-shellfuncs heartbeat/send_ua heartbeat/shellfuncs heartbeat/*.pyc heartbeat/AoEtarget heartbeat/CTDB heartbeat/ManageRAID heartbeat/ManageVE heartbeat/Squid heartbeat/SysInfo heartbeat/aws-vpc-route53 heartbeat/azure-events heartbeat/clvm heartbeat/conntrackd heartbeat/dnsupdate heartbeat/dummypy heartbeat/eDir88 heartbeat/fio heartbeat/galera heartbeat/gcp-pd-move heartbeat/gcp-vpc-move-ip heartbeat/gcp-vpc-move-route heartbeat/gcp-vpc-move-vip heartbeat/iSCSILogicalUnit heartbeat/iSCSITarget heartbeat/jira heartbeat/kamailio heartbeat/lxc heartbeat/lxd-info heartbeat/machine-info heartbeat/mariadb heartbeat/mpathpersist heartbeat/nfsnotify heartbeat/openstack-info heartbeat/rabbitmq-cluster heartbeat/redis heartbeat/rsyslog heartbeat/sg_persist heartbeat/slapd heartbeat/smb-share heartbeat/storage-mon heartbeat/sybaseASE heartbeat/syslog-ng heartbeat/vsftpd include/agent_config.h include/config.h include/config.h.in include/stamp-h1 include/stamp-h2 ldirectord/ldirectord ldirectord/ldirectord.8 ldirectord/OCF/ldirectord ldirectord/init.d/ldirectord ldirectord/init.d/ldirectord.debian ldirectord/init.d/ldirectord.debian.default ldirectord/systemd/ldirectord.service systemd/resource-agents.conf tools/findif tools/nfsconvert tools/ocf-tester tools/send_arp tools/storage_mon tools/tickle_tcp tools/ocft/README tools/ocft/README.zh_CN tools/ocft/caselib tools/ocft/ocft *.cache *.upgrade.xml py-compile ylwrap __pycache__ # BEAM Entries *.beam parser-messages MISC_ERRORS cscope.files cscope.out patches updates logs # OS and Editor Artifacts .DS_Store .bomb *.rej *.bz2 *.gz *.xz *.sed *.diff *.patch *.gres *~ # Misc HTML TAGS GPATH GRTAGS GSYMS GTAGS .gres.* *.orig .gdb_history *~ \#* .changes pacemaker.tar.gz diff --git a/doc/man/Makefile.am b/doc/man/Makefile.am index e90894cb9..1093717fe 100644 --- a/doc/man/Makefile.am +++ b/doc/man/Makefile.am @@ -1,256 +1,256 @@ # # doc: Linux-HA resource agents # # Copyright (C) 2009 Florian Haas # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # MAINTAINERCLEANFILES = Makefile.in EXTRA_DIST = $(doc_DATA) $(REFENTRY_STYLESHEET) \ mkappendix.sh ralist.sh CLEANFILES = $(man_MANS) $(xmlfiles) metadata-*.xml STYLESHEET_PREFIX ?= http://docbook.sourceforge.net/release/xsl/current MANPAGES_STYLESHEET ?= $(STYLESHEET_PREFIX)/manpages/docbook.xsl HTML_STYLESHEET ?= $(STYLESHEET_PREFIX)/xhtml/docbook.xsl FO_STYLESHEET ?= $(STYLESHEET_PREFIX)/fo/docbook.xsl REFENTRY_STYLESHEET ?= ra2refentry.xsl XSLTPROC_OPTIONS ?= --xinclude XSLTPROC_MANPAGES_OPTIONS ?= $(XSLTPROC_OPTIONS) XSLTPROC_HTML_OPTIONS ?= $(XSLTPROC_OPTIONS) XSLTPROC_FO_OPTIONS ?= $(XSLTPROC_OPTIONS) radir = $(abs_top_builddir)/heartbeat # required for out-of-tree build symlinkstargets = \ ocf-distro ocf.py ocf-rarun ocf-returncodes \ findif.sh apache-conf.sh http-mon.sh mysql-common.sh \ - nfsserver-redhat.sh ora-common.sh + nfsserver-redhat.sh openstack-common.sh ora-common.sh preptree: for i in $(symlinkstargets); do \ if [ ! -f $(radir)/$$i ]; then \ rm -rf $(radir)/$$i; \ ln -sf $(abs_top_srcdir)/heartbeat/$$i $(radir)/$$i; \ fi; \ done $(radir)/%: $(abs_top_srcdir)/heartbeat/% if [ ! -f $@ ]; then \ ln -sf $< $@; \ fi # OCF_ROOT=. is necessary due to a sanity check in ocf-shellfuncs # (which tests whether $OCF_ROOT points to a directory metadata-%.xml: $(radir)/% preptree OCF_ROOT=. OCF_FUNCTIONS_DIR=$(radir) $< meta-data > $@ metadata-IPv6addr.xml: $(radir)/IPv6addr OCF_ROOT=. OCF_FUNCTIONS_DIR=$(radir) $< meta-data > $@ clean-local: find $(radir) -type l -exec rm -rf {} \; # Please note: we can't name the man pages # ocf:heartbeat:. Believe me, I've tried. It looks like it # works, but then it doesn't. While make can deal correctly with # colons in target names (when properly escaped), it royally messes up # when it is deals with _dependencies_ that contain colons. See Bug # 12126 on savannah.gnu.org. But, maybe it gets fixed soon, it was # first reported in 1995 and added to Savannah in in 2005... if BUILD_DOC man_MANS = ocf_heartbeat_AoEtarget.7 \ ocf_heartbeat_AudibleAlarm.7 \ ocf_heartbeat_ClusterMon.7 \ ocf_heartbeat_CTDB.7 \ ocf_heartbeat_Delay.7 \ ocf_heartbeat_Dummy.7 \ ocf_heartbeat_EvmsSCC.7 \ ocf_heartbeat_Evmsd.7 \ ocf_heartbeat_Filesystem.7 \ ocf_heartbeat_ICP.7 \ ocf_heartbeat_IPaddr.7 \ ocf_heartbeat_IPaddr2.7 \ ocf_heartbeat_IPsrcaddr.7 \ ocf_heartbeat_LVM.7 \ ocf_heartbeat_LVM-activate.7 \ ocf_heartbeat_LinuxSCSI.7 \ ocf_heartbeat_MailTo.7 \ ocf_heartbeat_ManageRAID.7 \ ocf_heartbeat_ManageVE.7 \ ocf_heartbeat_NodeUtilization.7 \ ocf_heartbeat_Pure-FTPd.7 \ ocf_heartbeat_Raid1.7 \ ocf_heartbeat_Route.7 \ ocf_heartbeat_SAPDatabase.7 \ ocf_heartbeat_SAPInstance.7 \ ocf_heartbeat_SendArp.7 \ ocf_heartbeat_ServeRAID.7 \ ocf_heartbeat_SphinxSearchDaemon.7 \ ocf_heartbeat_Squid.7 \ ocf_heartbeat_Stateful.7 \ ocf_heartbeat_SysInfo.7 \ ocf_heartbeat_VIPArip.7 \ ocf_heartbeat_VirtualDomain.7 \ ocf_heartbeat_WAS.7 \ ocf_heartbeat_WAS6.7 \ ocf_heartbeat_WinPopup.7 \ ocf_heartbeat_Xen.7 \ ocf_heartbeat_Xinetd.7 \ ocf_heartbeat_ZFS.7 \ ocf_heartbeat_aliyun-vpc-move-ip.7 \ ocf_heartbeat_anything.7 \ ocf_heartbeat_apache.7 \ ocf_heartbeat_asterisk.7 \ ocf_heartbeat_aws-vpc-move-ip.7 \ ocf_heartbeat_aws-vpc-route53.7 \ ocf_heartbeat_awseip.7 \ ocf_heartbeat_awsvip.7 \ ocf_heartbeat_azure-lb.7 \ ocf_heartbeat_clvm.7 \ ocf_heartbeat_conntrackd.7 \ ocf_heartbeat_crypt.7 \ ocf_heartbeat_db2.7 \ ocf_heartbeat_dhcpd.7 \ ocf_heartbeat_docker.7 \ ocf_heartbeat_docker-compose.7 \ ocf_heartbeat_dovecot.7 \ ocf_heartbeat_dnsupdate.7 \ ocf_heartbeat_dummypy.7 \ ocf_heartbeat_eDir88.7 \ ocf_heartbeat_ethmonitor.7 \ ocf_heartbeat_exportfs.7 \ ocf_heartbeat_fio.7 \ ocf_heartbeat_galera.7 \ ocf_heartbeat_garbd.7 \ ocf_heartbeat_gcp-ilb.7 \ ocf_heartbeat_gcp-vpc-move-ip.7 \ ocf_heartbeat_iSCSILogicalUnit.7 \ ocf_heartbeat_iSCSITarget.7 \ ocf_heartbeat_iface-bridge.7 \ ocf_heartbeat_iface-vlan.7 \ ocf_heartbeat_ipsec.7 \ ocf_heartbeat_ids.7 \ ocf_heartbeat_iscsi.7 \ ocf_heartbeat_jboss.7 \ ocf_heartbeat_jira.7 \ ocf_heartbeat_kamailio.7 \ ocf_heartbeat_lvmlockd.7 \ ocf_heartbeat_lxc.7 \ ocf_heartbeat_lxd-info.7 \ ocf_heartbeat_machine-info.7 \ ocf_heartbeat_mariadb.7 \ ocf_heartbeat_mdraid.7 \ ocf_heartbeat_minio.7 \ ocf_heartbeat_mpathpersist.7 \ ocf_heartbeat_mysql.7 \ ocf_heartbeat_mysql-proxy.7 \ ocf_heartbeat_nagios.7 \ ocf_heartbeat_named.7 \ ocf_heartbeat_nfsnotify.7 \ ocf_heartbeat_nfsserver.7 \ ocf_heartbeat_nginx.7 \ ocf_heartbeat_nvmet-subsystem.7 \ ocf_heartbeat_nvmet-namespace.7 \ ocf_heartbeat_nvmet-port.7 \ ocf_heartbeat_openstack-info.7 \ ocf_heartbeat_openstack-cinder-volume.7 \ ocf_heartbeat_openstack-floating-ip.7 \ ocf_heartbeat_openstack-virtual-ip.7 \ ocf_heartbeat_oraasm.7 \ ocf_heartbeat_oracle.7 \ ocf_heartbeat_oralsnr.7 \ ocf_heartbeat_ovsmonitor.7 \ ocf_heartbeat_pgagent.7 \ ocf_heartbeat_pgsql.7 \ ocf_heartbeat_pingd.7 \ ocf_heartbeat_podman.7 \ ocf_heartbeat_portblock.7 \ ocf_heartbeat_postfix.7 \ ocf_heartbeat_pound.7 \ ocf_heartbeat_proftpd.7 \ ocf_heartbeat_rabbitmq-cluster.7 \ ocf_heartbeat_rabbitmq-server-ha.7 \ ocf_heartbeat_redis.7 \ ocf_heartbeat_rkt.7 \ ocf_heartbeat_rsyncd.7 \ ocf_heartbeat_rsyslog.7 \ ocf_heartbeat_scsi2reservation.7 \ ocf_heartbeat_sfex.7 \ ocf_heartbeat_slapd.7 \ ocf_heartbeat_smb-share.7 \ ocf_heartbeat_sybaseASE.7 \ ocf_heartbeat_sg_persist.7 \ ocf_heartbeat_storage-mon.7 \ ocf_heartbeat_symlink.7 \ ocf_heartbeat_syslog-ng.7 \ ocf_heartbeat_tomcat.7 \ ocf_heartbeat_varnish.7 \ ocf_heartbeat_vdo-vol.7 \ ocf_heartbeat_vmware.7 \ ocf_heartbeat_vsftpd.7 \ ocf_heartbeat_zabbixserver.7 if USE_IPV6ADDR_AGENT man_MANS += ocf_heartbeat_IPv6addr.7 endif if BUILD_AZURE_EVENTS man_MANS += ocf_heartbeat_azure-events.7 endif if BUILD_GCP_PD_MOVE man_MANS += ocf_heartbeat_gcp-pd-move.7 endif if BUILD_GCP_VPC_MOVE_ROUTE man_MANS += ocf_heartbeat_gcp-vpc-move-route.7 endif if BUILD_GCP_VPC_MOVE_VIP man_MANS += ocf_heartbeat_gcp-vpc-move-vip.7 endif xmlfiles = $(man_MANS:.7=.xml) %.1 %.5 %.7 %.8: %.xml $(XSLTPROC) \ $(XSLTPROC_MANPAGES_OPTIONS) \ $(MANPAGES_STYLESHEET) $< ocf_heartbeat_%.xml: metadata-%.xml $(srcdir)/$(REFENTRY_STYLESHEET) $(XSLTPROC) --novalid \ --stringparam package $(PACKAGE_NAME) \ --stringparam version $(VERSION) \ --output $@ \ $(srcdir)/$(REFENTRY_STYLESHEET) $< ocf_resource_agents.xml: $(xmlfiles) mkappendix.sh ./mkappendix.sh $(xmlfiles) > $@ %.html: %.xml $(XSLTPROC) \ $(XSLTPROC_HTML_OPTIONS) \ --output $@ \ $(HTML_STYLESHEET) $< xml: ocf_resource_agents.xml endif diff --git a/heartbeat/Makefile.am b/heartbeat/Makefile.am index 8e0f2122c..67b400679 100644 --- a/heartbeat/Makefile.am +++ b/heartbeat/Makefile.am @@ -1,241 +1,242 @@ # Makefile.am for OCF RAs # # Author: Sun Jing Dong # Copyright (C) 2004 IBM # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # MAINTAINERCLEANFILES = Makefile.in EXTRA_DIST = $(ocf_SCRIPTS) $(ocfcommon_DATA) \ $(common_DATA) $(hb_DATA) $(dtd_DATA) \ README README.galera AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_srcdir)/linux-ha halibdir = $(libexecdir)/heartbeat ocfdir = $(OCF_RA_DIR_PREFIX)/heartbeat dtddir = $(datadir)/$(PACKAGE_NAME) dtd_DATA = ra-api-1.dtd metadata.rng ocf_PROGRAMS = if USE_IPV6ADDR_AGENT ocf_PROGRAMS += IPv6addr endif halib_PROGRAMS = if IPV6ADDR_COMPATIBLE halib_PROGRAMS += send_ua endif IPv6addr_SOURCES = IPv6addr.c IPv6addr_utils.c IPv6addr_LDADD = -lplumb $(LIBNETLIBS) send_ua_SOURCES = send_ua.c IPv6addr_utils.c send_ua_LDADD = $(LIBNETLIBS) ocf_SCRIPTS = AoEtarget \ AudibleAlarm \ ClusterMon \ CTDB \ Delay \ Dummy \ EvmsSCC \ Evmsd \ Filesystem \ ICP \ IPaddr \ IPaddr2 \ IPsrcaddr \ LVM \ LinuxSCSI \ lvmlockd \ LVM-activate \ MailTo \ ManageRAID \ ManageVE \ NodeUtilization \ Pure-FTPd \ Raid1 \ Route \ SAPDatabase \ SAPInstance \ SendArp \ ServeRAID \ SphinxSearchDaemon \ Squid \ Stateful \ SysInfo \ VIPArip \ VirtualDomain \ WAS \ WAS6 \ WinPopup \ Xen \ Xinetd \ ZFS \ aliyun-vpc-move-ip \ anything \ apache \ asterisk \ aws-vpc-move-ip \ aws-vpc-route53 \ awseip \ awsvip \ azure-lb \ clvm \ conntrackd \ crypt \ db2 \ dhcpd \ dnsupdate \ dummypy \ docker \ docker-compose \ dovecot \ eDir88 \ ethmonitor \ exportfs \ fio \ galera \ garbd \ gcp-ilb \ gcp-vpc-move-ip \ iSCSILogicalUnit \ iSCSITarget \ ids \ iface-bridge \ iface-vlan \ ipsec \ iscsi \ jboss \ jira \ kamailio \ lxc \ lxd-info \ machine-info \ mariadb \ mdraid \ minio \ mysql \ mysql-proxy \ nagios \ named \ nfsnotify \ nfsserver \ nginx \ nvmet-subsystem \ nvmet-namespace \ nvmet-port \ openstack-cinder-volume \ openstack-floating-ip \ openstack-info \ openstack-virtual-ip \ oraasm \ oracle \ oralsnr \ ovsmonitor \ pgagent \ pgsql \ pingd \ podman \ portblock \ postfix \ pound \ proftpd \ rabbitmq-cluster \ rabbitmq-server-ha \ redis \ rkt \ rsyncd \ rsyslog \ scsi2reservation \ sfex \ sg_persist \ mpathpersist \ slapd \ smb-share \ storage-mon \ sybaseASE \ symlink \ syslog-ng \ tomcat \ varnish \ vdo-vol \ vmware \ vsftpd \ zabbixserver if BUILD_AZURE_EVENTS ocf_SCRIPTS += azure-events endif if BUILD_GCP_PD_MOVE ocf_SCRIPTS += gcp-pd-move endif if BUILD_GCP_VPC_MOVE_ROUTE ocf_SCRIPTS += gcp-vpc-move-route endif if BUILD_GCP_VPC_MOVE_VIP ocf_SCRIPTS += gcp-vpc-move-vip endif ocfcommondir = $(OCF_LIB_DIR_PREFIX)/heartbeat ocfcommon_DATA = ocf-shellfuncs \ ocf-binaries \ ocf-directories \ ocf-returncodes \ ocf-rarun \ ocf-distro \ apache-conf.sh \ http-mon.sh \ sapdb-nosha.sh \ sapdb.sh \ lvm-clvm.sh \ lvm-plain.sh \ lvm-tag.sh \ + openstack-common.sh \ ora-common.sh \ mysql-common.sh \ nfsserver-redhat.sh \ findif.sh \ ocf.py # Legacy locations hbdir = $(sysconfdir)/ha.d hb_DATA = shellfuncs check: $(ocf_SCRIPTS:=.check) %.check: % OCF_ROOT=$(abs_srcdir) OCF_FUNCTIONS_DIR=$(abs_srcdir) ./$< meta-data | xmllint --path $(abs_srcdir) --noout --relaxng $(abs_srcdir)/metadata.rng - do_spellcheck = printf '[%s]\n' "$(agent)"; \ OCF_ROOT=$(abs_srcdir) OCF_FUNCTIONS_DIR=$(abs_srcdir) \ ./$(agent) meta-data 2>/dev/null \ | xsltproc $(top_srcdir)/make/extract_text.xsl - \ | aspell pipe list -d en_US --ignore-case \ --home-dir=$(top_srcdir)/make -p spellcheck-ignore \ | sed -n 's|^&\([^:]*\):.*|\1|p'; spellcheck: @$(foreach agent,$(ocf_SCRIPTS), $(do_spellcheck)) clean-local: rm -rf __pycache__ *.pyc diff --git a/heartbeat/openstack-cinder-volume b/heartbeat/openstack-cinder-volume index 9297be4ef..b384c0a3b 100755 --- a/heartbeat/openstack-cinder-volume +++ b/heartbeat/openstack-cinder-volume @@ -1,327 +1,291 @@ #!/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 +. ${OCF_FUNCTIONS_DIR}/openstack-common.sh + # Defaults -OCF_RESKEY_openstackcli_default="/usr/bin/openstack" OCF_RESKEY_volume_local_check_default="true" -OCF_RESKEY_insecure_default="false" -: ${OCF_RESKEY_openstackcli=${OCF_RESKEY_openstackcli_default}} : ${OCF_RESKEY_volume_local_check=${OCF_RESKEY_volume_local_check_default}} -: ${OCF_RESKEY_insecure=${OCF_RESKEY_insecure_default}} ####################################################################### USAGE="usage: $0 {start|stop|status|meta-data}"; ############################################################################### ############################################################################### # # Functions # ############################################################################### metadata() { cat < 1.0 Resource Agent to attach a cinder volume to an instance. It relies on attributes given by openstack-info resource agent (openstack_id attribute). Attach a cinder volume - - -Path to command line tools for openstack. - -Path to Openstack CLI tool - - +END + +common_meta_data +cat < This option allows the cluster to monitor the cinder volume presence without calling the API. Monitor cinder volume locally - - -Valid Openstack credentials as openrc file from api_access/openrc. - -openrc file - - - -Cinder volume identifier to use to attach the bloc storage. +Cinder volume identifier to use to attach the block storage. Volume ID - - - -Allow insecure connections - -Allow insecure connections - - - END } -if [ "${OCF_RESKEY_insecure}" = true ]; then - OCF_RESKEY_openstackcli="${OCF_RESKEY_openstackcli} --insecure" -fi - _get_node_id() { node_id=$(${HA_SBIN_DIR}/attrd_updater --query -n openstack_id -N $(crm_node -n) | awk -F= '{gsub("\"","");print $NF}') if ! echo $node_id|grep -P "^[0-9a-f]{8}-([0-9a-f]{4}-){3}[0-9a-f]{12}$"; then ocf_exit_reason "openstack_id attribute must be set for node $crm_node" exit $OCF_ERR_CONFIGURED fi } osvol_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 + get_config if ! $OCF_RESKEY_openstackcli volume list|grep -q $OCF_RESKEY_volume_id ; then ocf_exit_reason "volume-id $OCF_RESKEY_volume_id not found" return $OCF_ERR_CONFIGURED fi ${HA_SBIN_DIR}/attrd_updater --query -n openstack_id -N $(crm_node -n) > /dev/null 2>&1 if [ $? -ne 0 ] ; then ocf_log warn "attr_updater failed to get openstack_id attribute of node $OCF_RESOURCE_INSTANCE" return $OCF_ERR_GENERIC fi return $OCF_SUCCESS } osvol_monitor() { local result local node_id local short_volume_id node_id=$(_get_node_id) 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 lsblk /dev/disk/by-id/virtio-$short_volume_id 1>/dev/null 2>&1; then return $OCF_SUCCESS else ocf_log warn "$OCF_RESKEY_volume_id is not attached to instance $node_id" return $OCF_NOT_RUNNING fi fi # # 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| grep -P -o "'server_id': '[0-9a-f]{8}-([0-9a-f]{4}-){3}[0-9a-f]{12}'"| grep -P -o "[0-9a-f]{8}-([0-9a-f]{4}-){3}[0-9a-f]{12}") 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 if [ "$node_id" != "$attached_server_id" ] ; then ocf_log warn "$OCF_RESKEY_volume_id is not attached to this instance" return $OCF_NOT_RUNNING 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=$(_get_node_id) # # Detach 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 # # Detach 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 case $__OCF_ACTION in start) osvol_validate || exit $? osvol_start;; stop) osvol_validate || exit $? osvol_stop;; monitor|status) osvol_validate || exit $? osvol_monitor;; validate-all) osvol_validate ;; *) echo $USAGE exit $OCF_ERR_UNIMPLEMENTED ;; esac exit $? diff --git a/heartbeat/openstack-common.sh b/heartbeat/openstack-common.sh new file mode 100644 index 000000000..88ed4ba69 --- /dev/null +++ b/heartbeat/openstack-common.sh @@ -0,0 +1,156 @@ +OCF_RESKEY_clouds_yaml_default="$HOME/.config/openstack/clouds.yaml" +OCF_RESKEY_openstackcli_default="/usr/bin/openstack" +OCF_RESKEY_insecure_default="false" + +: ${OCF_RESKEY_clouds_yaml=${OCF_RESKEY_clouds_yaml_default}} +: ${OCF_RESKEY_openstackcli=${OCF_RESKEY_openstackcli_default}} +: ${OCF_RESKEY_insecure=${OCF_RESKEY_insecure_default}} + +if ocf_is_true "${OCF_RESKEY_insecure}"; then + OCF_RESKEY_openstackcli="${OCF_RESKEY_openstackcli} --insecure" +fi + +common_meta_data() { + cat < + +Openstack clouds.yaml config file. + +clouds.yaml config file + + + + + +Openstack cloud (from ~/.config/openstack/clouds.yaml). + +Cloud from clouds.yaml + + + + + +Openstack credentials as openrc file from api_access/openrc. + +openrc file + + + + + +Keystone Auth URL + +Keystone Auth URL + + + + + +Username. + +Username + + + + + +Password. + +Password + + + + + +Keystone Project. + +Keystone Project + + + + + +Keystone User Domain Name. + +Keystone User Domain Name + + + + + +Keystone Project Domain Name. + +Keystone Project Domain Name + + + + + +Path to command line tools for openstack. + +Path to Openstack CLI tool + + + + + +Allow insecure connections + +Allow insecure connections + + +END +} + +get_config() { + if [ -n "$OCF_RESKEY_clouds_yaml" ]; then + if [ ! -f "$OCF_RESKEY_clouds_yaml" ]; then + ocf_exit_reason "$OCF_RESKEY_clouds_yaml does not exist" + return $OCF_ERR_CONFIGURED + fi + if [ -z "$OCF_RESKEY_cloud" ]; then + ocf_exit_reason "cloud: $OCF_RESKEY_cloud not found in $OCF_RESKEY_clouds_yaml" + return $OCF_ERR_CONFIGURED + fi + OCF_RESKEY_openstackcli="${OCF_RESKEY_openstackcli} --os-cloud $OCF_RESKEY_cloud" + elif [ -n "$OCF_RESKEY_openrc" ]; then + if [ ! -f "$OCF_RESKEY_openrc" ]; then + ocf_exit_reason "$OCF_RESKEY_openrc does not exist" + return $OCF_ERR_CONFIGURED + fi + . $OCF_RESKEY_openrc + else + if [ -z "$OCF_RESKEY_auth_url" ]; then + ocf_exit_reason "auth_url not set" + return $OCF_ERR_CONFIGURED + fi + if [ -z "$OCF_RESKEY_username" ]; then + ocf_exit_reason "username not set" + return $OCF_ERR_CONFIGURED + fi + if [ -z "$OCF_RESKEY_password" ]; then + ocf_exit_reason "password not set" + return $OCF_ERR_CONFIGURED + fi + if [ -z "$OCF_RESKEY_project_name" ]; then + ocf_exit_reason "project_name not set" + return $OCF_ERR_CONFIGURED + fi + if [ -z "$OCF_RESKEY_user_domain_name" ]; then + ocf_exit_reason "user_domain_name not set" + return $OCF_ERR_CONFIGURED + fi + if [ -z "$OCF_RESKEY_project_domain_name" ]; then + ocf_exit_reason " not set" + return $OCF_ERR_CONFIGURED + fi + + OCF_RESKEY_openstackcli="${OCF_RESKEY_openstackcli} --os-auth-url $OCF_RESKEY_auth_url" + OCF_RESKEY_openstackcli="${OCF_RESKEY_openstackcli} --os-username $OCF_RESKEY_username" + OCF_RESKEY_openstackcli="${OCF_RESKEY_openstackcli} --os-password $OCF_RESKEY_password" + OCF_RESKEY_openstackcli="${OCF_RESKEY_openstackcli} --os-project-name $OCF_RESKEY_project_name" + OCF_RESKEY_openstackcli="${OCF_RESKEY_openstackcli} --os-user-domain-name $OCF_RESKEY_user_domain_name" + OCF_RESKEY_openstackcli="${OCF_RESKEY_openstackcli} --os-project-domain-name $OCF_RESKEY_project_domain_name" + fi +} diff --git a/heartbeat/openstack-floating-ip b/heartbeat/openstack-floating-ip index 542861392..53ffbd3c0 100755 --- a/heartbeat/openstack-floating-ip +++ b/heartbeat/openstack-floating-ip @@ -1,290 +1,254 @@ #!/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_insecure_default="false" +. ${OCF_FUNCTIONS_DIR}/openstack-common.sh -: ${OCF_RESKEY_openstackcli=${OCF_RESKEY_openstackcli_default}} -: ${OCF_RESKEY_insecure=${OCF_RESKEY_insecure_default}} +# Defaults ####################################################################### USAGE="usage: $0 {start|stop|status|meta-data}"; ############################################################################### ############################################################################### # # Functions # ############################################################################### metadata() { cat < 1.0 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. Move a floating IP - - -Path to command line tools for openstack. - -Path to Openstack CLI tool - - +END - - -Valid Openstack credentials as openrc file from api_access/openrc. - -openrc file - - +common_meta_data +cat < Floating IP Identifier. IP ID Subnet Identifier to use to attach the address. Subnet ID - - -Allow insecure connections - -Allow insecure connections - - - END } -if [ "${OCF_RESKEY_insecure}" = true ]; then - OCF_RESKEY_openstackcli="${OCF_RESKEY_openstackcli} --insecure" -fi - 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 + get_config 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 $(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 node_port_ids=$(${HA_SBIN_DIR}/attrd_updater --query -n openstack_ports -N $(crm_node -n) \ | 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} -S status -n openstack_floating_ip -v $floating_ip return $OCF_SUCCESS fi done ${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 down $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 $(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}") 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 ocf_log info "Successfully brought up $OCF_RESKEY_ip_id" 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 case $__OCF_ACTION in start) osflip_validate || exit $? osflip_start;; stop) osflip_validate || exit $? osflip_stop;; monitor) osflip_validate || exit $? osflip_monitor;; validate-all) osflip_validate ;; *) echo $USAGE exit $OCF_ERR_UNIMPLEMENTED ;; esac exit $? diff --git a/heartbeat/openstack-info.in b/heartbeat/openstack-info.in index d74a31eb7..c10564a2c 100755 --- a/heartbeat/openstack-info.in +++ b/heartbeat/openstack-info.in @@ -1,304 +1,270 @@ #!/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_openstackcli_default="/usr/bin/openstack" OCF_RESKEY_pythoncli_default="@PYTHON@" -OCF_RESKEY_insecure_default="false" : ${OCF_RESKEY_curlcli=${OCF_RESKEY_curlcli_default}} -: ${OCF_RESKEY_openstackcli=${OCF_RESKEY_openstackcli_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}} -: ${OCF_RESKEY_insecure=${OCF_RESKEY_insecure_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 - - -Valid Openstack credentials as openrc file from api_access/openrc. - -openrc file - - - Path to command line cURL binary. Path to cURL binary - - -Path to command line tools for openstack. - -Path to Openstack CLI tool - - - Path to command line Python interpreter. Path to Python interpreter - - -Allow insecure connections - -Allow insecure connections - - - END } ####################################################################### -if [ "${OCF_RESKEY_insecure}" = true ]; then - OCF_RESKEY_openstackcli="${OCF_RESKEY_openstackcli} --insecure" -fi - OSInfoStats() { local result local value local node local node_id - . $OCF_RESKEY_openrc + 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=$($OCF_RESKEY_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=$($OCF_RESKEY_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 $($OCF_RESKEY_openstackcli port list \ --format value \ --column id \ --server $node_id); do subnet_id=$($OCF_RESKEY_openstackcli port show \ --format json \ --column fixed_ips \ ${port_id} | grep -P '\"subnet_id\": \".*\",$' | grep -P -o '[0-9a-f]{8}-([0-9a-f]{4}-){3}[0-9a-f]{12}') value+="${subnet_id}:${port_id}," done value=$(echo ${value} | sed -e 's/,$//g') ${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" - 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 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 $? diff --git a/heartbeat/openstack-virtual-ip b/heartbeat/openstack-virtual-ip index ee8951980..c0eb11393 100755 --- a/heartbeat/openstack-virtual-ip +++ b/heartbeat/openstack-virtual-ip @@ -1,294 +1,258 @@ #!/bin/sh # # # OCF resource agent to move a virtual 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_insecure_default="false" +. ${OCF_FUNCTIONS_DIR}/openstack-common.sh -: ${OCF_RESKEY_openstackcli=${OCF_RESKEY_openstackcli_default}} -: ${OCF_RESKEY_insecure=${OCF_RESKEY_insecure_default}} +# Defaults ####################################################################### USAGE="usage: $0 {start|stop|status|meta-data}"; ############################################################################### ############################################################################### # # Functions # ############################################################################### metadata() { cat < 1.0 Resource Agent to move a virtual IP address from an instance to another one by adding an allowed-address pair associated with an instance port. It relies on attributes given by openstack-info resource agent (openstack_ports, openstack_id attributes). The attribute called "openstack_virtual_ip" is updated. Move a virtual IP - - -Path to command line tools for openstack. - -Path to Openstack CLI tool - - +END - - -Valid Openstack credentials as openrc file from api_access/openrc. - -openrc file - - +common_meta_data +cat < Virtual IP Address. IP Address Subnet Identifier to use to attach the address. Subnet ID - - -Allow insecure connections - -Allow insecure connections - - - END } -if [ "${OCF_RESKEY_insecure}" = true ]; then - OCF_RESKEY_openstackcli="${OCF_RESKEY_openstackcli} --insecure" -fi - osvip_port_id() { # Get port_id from subnet_id 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}") echo ${node_port_id} } osvip_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 + get_config ${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 } osvip_monitor() { local result node_port_id=$(osvip_port_id) result=$($OCF_RESKEY_openstackcli port show \ --format value \ --column allowed_address_pairs \ ${node_port_id}) if echo $result | grep -q $OCF_RESKEY_ip ; then ${HA_SBIN_DIR}/attrd_updater ${OCF_RESKEY_delay} -S status -n openstack_virtual_ip -v $OCF_RESKEY_ip return $OCF_SUCCESS fi ${HA_SBIN_DIR}/attrd_updater ${OCF_RESKEY_delay} -D -S state -n openstack_virtual_ip ocf_log warn "$OCF_RESKEY_ip is not attached to any fixed address" return $OCF_NOT_RUNNING } osvip_stop() { node_port_id=$(osvip_port_id) ocf_log info "Bringing down IP address $OCF_RESKEY_ip" osvip_monitor if [ $? = $OCF_NOT_RUNNING ]; then ocf_log info "Address $OCF_RESKEY_ip already down" return $OCF_SUCCESS fi mac_address=$($OCF_RESKEY_openstackcli port show \ --format value \ --column mac_address \ $node_port_id) echo ${mac_address} | grep -q -P "^([0-9a-f]{2}:){5}[0-9a-f]{2}$" if [ $? -ne 0 ]; then ocf_log error "MAC address '${mac_address}' is not valid." return $OCF_ERR_GENERIC fi if ! $OCF_RESKEY_openstackcli port unset \ --allowed-address \ ip-address=$OCF_RESKEY_ip,mac-address=${mac_address} \ $node_port_id; then return $OCF_ERR_GENERIC fi osvip_monitor if [ $? != $OCF_NOT_RUNNING ]; then ocf_log error "Couldn't unset IP address $OCF_RESKEY_ip." return $OCF_ERR_GENERIC fi ocf_log info "Successfully brought down $OCF_RESKEY_ip" return $OCF_SUCCESS } osvip_start() { node_port_id=$(osvip_port_id) osvip_monitor if [ $? = $OCF_SUCCESS ]; then ocf_log info "$OCF_RESKEY_ip already started" return $OCF_SUCCESS fi ocf_log info "Moving IP address $OCF_RESKEY_ip to port ID $node_port_id" $OCF_RESKEY_openstackcli port set \ --allowed-address ip-address=$OCF_RESKEY_ip \ $node_port_id if [ $? != $OCF_SUCCESS ]; then ocf_log error "$OCF_RESKEY_ip Cannot be set to port $node_port_id" return $OCF_ERR_GENERIC fi osvip_monitor if [ $? != $OCF_SUCCESS ]; then ocf_log error "$OCF_RESKEY_ip Cannot be set to port $node_port_id" return $OCF_ERR_GENERIC fi ocf_log info "Successfully brought up $OCF_RESKEY_ip" 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 case $__OCF_ACTION in start) osvip_validate || exit $? osvip_start;; stop) osvip_validate || exit $? osvip_stop;; monitor) osvip_validate || exit $? osvip_monitor;; validate-all) osvip_validate ;; *) echo $USAGE exit $OCF_ERR_UNIMPLEMENTED ;; esac exit $?