All of lore.kernel.org
 help / color / mirror / Atom feed
* [Cluster-devel] Eaton fence agent and more power devices support
@ 2011-01-11 15:53 Arnaud Quette
  2011-01-20 12:35 ` Marek 'marx' Grác
  0 siblings, 1 reply; 6+ messages in thread
From: Arnaud Quette @ 2011-01-11 15:53 UTC (permalink / raw)
  To: cluster-devel.redhat.com

Hi Marek and the list,

First of all, happy new year to you all: health, happiness and ... high
availability ;-)

I've just derived a fence_eaton_snmp script, based on fence_apc_snmp.
You'll find attached the diff against the latest fence-agents repository.

This has been tested with the suitable hardware (Eaton Managed ePDU):
http://www.epdu.com
Can you please merge this for the next cman releases.

As a side note, I'm thinking about:
- making one fence_pdu_snmp to group all this code (sysOID brings the
smartness of knowing which data should be used), or at least create some
common grounds to factorize code,
- making a fence_nut_devices (or fence_power_devices) to use NUT [1] to do
the same for all supported serial / USB / SNMP / HTTP devices (ie UPS, PDU
and SCD).

Feedback and comments are welcome.

cheers,
Arnaud
--
[1] http://new.networkupstools.org & http://www.networkupstools.org
-- 
Linux / Unix Expert R&D - Eaton - http://powerquality.eaton.com
Network UPS Tools (NUT) Project Leader - http://www.networkupstools.org/
Debian Developer - http://www.debian.org
Free Software Developer - http://arnaud.quette.free.fr/
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://listman.redhat.com/archives/cluster-devel/attachments/20110111/3dca4f22/attachment.htm>
-------------- next part --------------
diff --git a/configure.ac b/configure.ac
index fd441e7..639769f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -224,6 +224,7 @@ AC_CONFIG_FILES([Makefile
 		 fence/agents/cpint/Makefile
 		 fence/agents/drac/Makefile
 		 fence/agents/drac5/Makefile
+		 fence/agents/eaton_snmp/Makefile
 		 fence/agents/egenera/Makefile
 		 fence/agents/eps/Makefile
 		 fence/agents/ibmblade/Makefile
diff --git a/fence/agents/Makefile.am b/fence/agents/Makefile.am
index 3a91ed4..945b49b 100644
--- a/fence/agents/Makefile.am
+++ b/fence/agents/Makefile.am
@@ -13,6 +13,7 @@ SUBDIRS 		= lib \
 			  cpint \
 			  drac \
 			  drac5 \
+			  eaton_snmp \
 			  egenera \
 			  eps \
 			  ibmblade \
diff --git a/fence/agents/eaton_snmp/Makefile.am b/fence/agents/eaton_snmp/Makefile.am
new file mode 100644
index 0000000..dad91c9
--- /dev/null
+++ b/fence/agents/eaton_snmp/Makefile.am
@@ -0,0 +1,16 @@
+MAINTAINERCLEANFILES	= Makefile.in
+
+TARGET			= fence_eaton_snmp
+
+EXTRA_DIST		= $(TARGET).py \
+			  README
+
+sbin_SCRIPTS		= $(TARGET)
+
+dist_man_MANS		= $(TARGET).8
+
+include $(top_srcdir)/make/fencebuild.mk
+include $(top_srcdir)/make/fenceman.mk
+
+clean-local: clean-man
+	rm -f $(TARGET)
diff --git a/fence/agents/eaton_snmp/README b/fence/agents/eaton_snmp/README
new file mode 100644
index 0000000..82619d7
--- /dev/null
+++ b/fence/agents/eaton_snmp/README
@@ -0,0 +1,20 @@
+This is an snmp based fence agent for Eaton power distribution units to be used
+with RHEL4 Red Hat Cluster Suite.
+
+In order to use this agent, you will need to have net-snmp-utils installed 
+on every node in your cluster. net-snmp-utils is scheduled for inclusion 
+in the base RHEL distribution for Update 4, and is yummable in FC5.
+
+To use the agent, cp the agent to the /sbin directory on every
+cluster node.
+
+Then define a <fencedevice> in the cluster.conf file with
+agent="fence_eaton_snmp" as an attribute, and use it that way.
+Note, please, that the GUI does not support this agent yet, and you will have
+to edit your cluster.conf by hand and then propagate it yourself. If you need
+help with this, email me at the address below.
+
+The interface for the fence_eaton_snmp agent is identical to the existing
+fence_apc_snmp agent, upon which it has been derived.
+
+--Arnaud Quette - ArnaudQuette at Eaton.com
diff --git a/fence/agents/eaton_snmp/fence_eaton_snmp.py b/fence/agents/eaton_snmp/fence_eaton_snmp.py
new file mode 100755
index 0000000..b02cfd1
--- /dev/null
+++ b/fence/agents/eaton_snmp/fence_eaton_snmp.py
@@ -0,0 +1,177 @@
+#!/usr/bin/python
+
+# The Following agent has been tested on:
+# - Eaton ePDU managed - SNMP v1
+
+import sys, re, pexpect
+sys.path.append("@FENCEAGENTSLIBDIR@")
+from fencing import *
+from fencing_snmp import *
+
+#BEGIN_VERSION_GENERATION
+RELEASE_VERSION="Eaton SNMP fence agent"
+REDHAT_COPYRIGHT=""
+BUILD_DATE=""
+#END_VERSION_GENERATION
+
+### CONSTANTS ###
+# oid defining fence device
+OID_SYS_OBJECT_ID='.1.3.6.1.2.1.1.2.0'
+
+### GLOBAL VARIABLES ###
+# Device - see EatonManagedePDU
+device=None
+
+# Port ID
+port_id=None
+# Switch ID
+switch_id=None
+
+# Classes describing Device params
+class EatonManagedePDU:
+	status_oid=      '.1.3.6.1.4.1.534.6.6.6.1.2.2.1.3.%d'
+	control_oid=     '.1.3.6.1.4.1.534.6.6.6.1.2.2.1.3.%d'
+	outlet_table_oid='.1.3.6.1.4.1.534.6.6.6.1.2.2.1.1'
+	ident_str="Eaton Managed ePDU"
+	state_off=0
+	state_on=1
+	state_cycling=2
+	turn_off=0
+	turn_on=1
+	turn_cycle=2
+	# FIXME: what's this?
+	has_switches=False
+
+### FUNCTIONS ###
+def eaton_set_device(conn,options):
+	global device
+
+	agents_dir={'.1.3.6.1.4.1.534.6.6.6':EatonManagedePDU}
+
+	# First resolve type of Eaton
+	eaton_type=conn.walk(OID_SYS_OBJECT_ID)
+
+	if (not ((len(eaton_type)==1) and (agents_dir.has_key(eaton_type[0][1])))):
+		eaton_type=[[None,None]]
+
+	device=agents_dir[eaton_type[0][1]]
+
+	conn.log_command("Trying %s"%(device.ident_str))
+
+def eaton_resolv_port_id(conn,options):
+	global port_id,switch_id,device
+
+	if (device==None):
+		eaton_set_device(conn,options)
+
+	# Now we resolv port_id/switch_id
+	if ((options["-n"].isdigit()) and ((not device.has_switches) or (options["-s"].isdigit()))):
+		port_id=int(options["-n"])
+
+		if (device.has_switches):
+			switch_id=int(options["-s"])
+	else:
+		table=conn.walk(device.outlet_table_oid,30)
+
+		for x in table:
+			if (x[1].strip('"')==options["-n"]):
+				t=x[0].split('.')
+				if (device.has_switches):
+					port_id=int(t[len(t)-1])
+					switch_id=int(t[len(t)-3])
+				else:
+					port_id=int(t[len(t)-1])
+
+	if (port_id==None):
+		fail_usage("Can't find port with name %s!"%(options["-n"]))
+
+def get_power_status(conn,options):
+	global port_id,switch_id,device
+
+	if (port_id==None):
+		eaton_resolv_port_id(conn,options)
+
+	oid=((device.has_switches) and device.status_oid%(switch_id,port_id) or device.status_oid%(port_id))
+
+	(oid,status)=conn.get(oid)
+	return (status==str(device.state_on) and "on" or "off")
+
+def set_power_status(conn, options):
+	global port_id,switch_id,device
+
+	if (port_id==None):
+		eaton_resolv_port_id(conn,options)
+
+	oid=((device.has_switches) and device.control_oid%(switch_id,port_id) or device.control_oid%(port_id))
+
+	conn.set(oid,(options["-o"]=="on" and device.turn_on or device.turn_off))
+
+
+def get_outlets_status(conn, options):
+	global device
+
+	result={}
+
+	if (device==None):
+		eaton_set_device(conn,options)
+
+	res_ports=conn.walk(device.outlet_table_oid,30)
+
+	for x in res_ports:
+		t=x[0].split('.')
+
+		port_num=((device.has_switches) and "%s:%s"%(t[len(t)-3],t[len(t)-1]) or "%s"%(t[len(t)-1]))
+
+                port_name=x[1].strip('"')
+                port_status=""
+                result[port_num]=(port_name,port_status)
+
+        return result
+
+# Define new options
+def eaton_snmp_define_defaults():
+	all_opt["snmp_version"]["default"]="1"
+	all_opt["community"]["default"]="private"
+
+# Main agent method
+def main():
+	device_opt = [ "help", "version", "agent", "quiet", "verbose", "debug",
+		       "action", "ipaddr", "login", "passwd", "passwd_script",
+		       "test", "port", "separator", "no_login", "no_password",
+		       "snmp_version", "community", "snmp_auth_prot", "snmp_sec_level",
+		       "snmp_priv_prot", "snmp_priv_passwd", "snmp_priv_passwd_script",
+		       "udpport","inet4_only","inet6_only",
+		       "power_timeout", "shell_timeout", "login_timeout", "power_wait" ]
+
+	atexit.register(atexit_handler)
+
+	snmp_define_defaults ()
+	eaton_snmp_define_defaults()
+
+	options=check_input(device_opt,process_input(device_opt))
+
+        ## Support for -n [switch]:[plug] notation that was used before
+	if ((options.has_key("-n")) and (-1 != options["-n"].find(":"))):
+		(switch, plug) = options["-n"].split(":", 1)
+		if ((switch.isdigit()) and (plug.isdigit())):
+		        options["-s"] = switch
+			options["-n"] = plug
+
+	if (not (options.has_key("-s"))):
+		options["-s"]="1"
+
+	docs = { }
+	docs["shortdesc"] = "Fence agent for Eaton over SNMP"
+	docs["longdesc"] = "fence_eaton_snmp is an I/O Fencing agent \
+which can be used with the Eaton network power switch. It logs \
+into a device via SNMP and reboots a specified outlet. It supports \
+SNMP v1 and v3 with all combinations of  authenticity/privacy settings."
+	docs["vendorurl"] = "http://powerquality.eaton.com"
+	show_docs(options, docs)
+
+	# Operate the fencing device
+	result = fence_action(FencingSnmp(options), options, set_power_status, get_power_status, get_outlets_status)
+
+	sys.exit(result)
+if __name__ == "__main__":
+	main()

^ permalink raw reply related	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2011-01-24 13:31 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-01-11 15:53 [Cluster-devel] Eaton fence agent and more power devices support Arnaud Quette
2011-01-20 12:35 ` Marek 'marx' Grác
2011-01-24 12:18   ` Arnaud Quette
2011-01-24 12:47     ` Fabio M. Di Nitto
2011-01-24 13:19       ` Arnaud Quette
2011-01-24 13:31         ` Fabio M. Di Nitto

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.