fence-agents: master - library: Properly escape XML also in getopt mixed=".."
by Marek Grác
Gitweb: http://git.fedorahosted.org/git/?p=fence-agents.git;a=commitdiff;h=321a21...
Commit: 321a214d48eebfe94d0923d5a08195621a8682bc
Parent: 8cc5231e23406e24ea0136223c2a548e41aca5a2
Author: Marek 'marx' Grac <mgrac(a)redhat.com>
AuthorDate: Mon Dec 8 16:13:22 2014 +0100
Committer: Marek 'marx' Grac <mgrac(a)redhat.com>
CommitterDate: Mon Dec 8 16:13:22 2014 +0100
library: Properly escape XML also in getopt mixed=".."
---
fence/agents/lib/fencing.py.py | 5 ++---
1 files changed, 2 insertions(+), 3 deletions(-)
diff --git a/fence/agents/lib/fencing.py.py b/fence/agents/lib/fencing.py.py
index 645441f..5449373 100644
--- a/fence/agents/lib/fencing.py.py
+++ b/fence/agents/lib/fencing.py.py
@@ -534,8 +534,7 @@ def metadata(avail_opt, docs):
res = re.compile(r"^(.*?--\S+)\s+", re.IGNORECASE | re.S).search(mixed)
if None != res:
mixed = res.group(1)
- # @todo: replace with _encode_html_entities but update XML metadata in regression tests
- mixed = mixed.replace("<", "<").replace(">", ">")
+ mixed = _encode_html_entities(mixed)
print "\t\t<getopt mixed=\"" + mixed + "\" />"
if all_opt[option].has_key("choices"):
@@ -736,7 +735,7 @@ def fence_action(connection, options, set_power_fn, get_power_fn, get_outlet_lis
elif (options["--action"] == "list") or \
((options["--action"] == "monitor") and 1 == options["device_opt"].count("port")):
outlets = get_outlet_list(connection, options)
- ## keys can be numbers (port numbers) or strings (names of VM)
+ ## keys can be numbers (port numbers) or strings (names of VM, UUID)
for outlet_id in outlets.keys():
(alias, status) = outlets[outlet_id]
if options["--action"] != "monitor":
9 years, 6 months
fence-agents: master - fence_emerson: Add power-wait=5seconds because device is too fast
by Marek Grác
Gitweb: http://git.fedorahosted.org/git/?p=fence-agents.git;a=commitdiff;h=8cc523...
Commit: 8cc5231e23406e24ea0136223c2a548e41aca5a2
Parent: cf00fc93de753bca2e9c1720024a3a9c2bc9da99
Author: Marek 'marx' Grac <mgrac(a)redhat.com>
AuthorDate: Mon Dec 8 15:53:07 2014 +0100
Committer: Marek 'marx' Grac <mgrac(a)redhat.com>
CommitterDate: Mon Dec 8 16:01:43 2014 +0100
fence_emerson: Add power-wait=5seconds because device is too fast
---
fence/agents/emerson/fence_emerson.py | 1 +
tests/data/metadata/fence_emerson.xml | 2 +-
2 files changed, 2 insertions(+), 1 deletions(-)
diff --git a/fence/agents/emerson/fence_emerson.py b/fence/agents/emerson/fence_emerson.py
index 1ef911b..af7f132 100644
--- a/fence/agents/emerson/fence_emerson.py
+++ b/fence/agents/emerson/fence_emerson.py
@@ -50,6 +50,7 @@ def main():
atexit.register(atexit_handler)
+ all_opt["power_wait"]["default"] = "5"
options = check_input(device_opt, process_input(device_opt))
docs = {}
diff --git a/tests/data/metadata/fence_emerson.xml b/tests/data/metadata/fence_emerson.xml
index 3b49b56..1aa5474 100644
--- a/tests/data/metadata/fence_emerson.xml
+++ b/tests/data/metadata/fence_emerson.xml
@@ -139,7 +139,7 @@
</parameter>
<parameter name="power_wait" unique="0" required="0">
<getopt mixed="--power-wait=[seconds]" />
- <content type="string" default="0" />
+ <content type="string" default="5" />
<shortdesc lang="en">Wait X seconds after issuing ON/OFF</shortdesc>
</parameter>
<parameter name="shell_timeout" unique="0" required="0">
9 years, 6 months
fence-agents: master - [refactor] simplifying function metadata() + fix XML for fence_cisco_ucs
by Marek Grác
Gitweb: http://git.fedorahosted.org/git/?p=fence-agents.git;a=commitdiff;h=cf00fc...
Commit: cf00fc93de753bca2e9c1720024a3a9c2bc9da99
Parent: 64e405b09f024e59258d215a7127eea285d184d0
Author: Marek 'marx' Grac <mgrac(a)redhat.com>
AuthorDate: Thu Dec 4 23:50:14 2014 +0100
Committer: Marek 'marx' Grac <mgrac(a)redhat.com>
CommitterDate: Thu Dec 4 23:50:14 2014 +0100
[refactor] simplifying function metadata() + fix XML for fence_cisco_ucs
Two if-s where removed as they are no longer needed by fence agents. One of
its impact was that two fence agents has changed their XML metadata. In case
of fence_ovh it was because default value was set even when it should not be.
And in the case of cisco_ucs, default was not propagated properly because
it was empty string.
---
fence/agents/lib/fencing.py.py | 14 ++++----------
fence/agents/ovh/Makefile.am | 2 +-
fence/agents/ovh/fence_ovh.py | 1 -
tests/data/metadata/fence_cisco_ucs.xml | 2 +-
4 files changed, 6 insertions(+), 13 deletions(-)
diff --git a/fence/agents/lib/fencing.py.py b/fence/agents/lib/fencing.py.py
index 370e42f..645441f 100644
--- a/fence/agents/lib/fencing.py.py
+++ b/fence/agents/lib/fencing.py.py
@@ -507,7 +507,7 @@ def usage(avail_opt):
if len(value["help"]) != 0:
print " " + value["help"]
-def metadata(avail_opt, options, docs):
+def metadata(avail_opt, docs):
# avail_opt has to be unique, if there are duplicities then they should be removed
sorted_list = [(key, all_opt[key]) for key in list(set(avail_opt))]
sorted_list.sort(lambda x, y: cmp(x[0], y[0]))
@@ -519,8 +519,7 @@ def metadata(avail_opt, options, docs):
for (symlink, desc) in docs.get("symlink", []):
print "<symlink name=\"" + symlink + "\" shortdesc=\"" + desc + "\"/>"
print "<longdesc>" + docs["longdesc"] + "</longdesc>"
- if docs.has_key("vendorurl"):
- print "<vendor-url>" + docs["vendorurl"] + "</vendor-url>"
+ print "<vendor-url>" + docs["vendorurl"] + "</vendor-url>"
print "<parameters>"
for option, _ in sorted_list:
if all_opt[option].has_key("shortdesc"):
@@ -528,12 +527,7 @@ def metadata(avail_opt, options, docs):
default = ""
if all_opt[option].has_key("default"):
- default = str(all_opt[option]["default"])
- elif options.has_key("--" + all_opt[option]["longopt"]):
- default = "true"
-
- if default:
- default = "default=\"" + _encode_html_entities(default) + "\" "
+ default = "default=\"" + _encode_html_entities(str(all_opt[option]["default"])) + "\" "
mixed = all_opt[option]["help"]
## split it between option and help text
@@ -713,7 +707,7 @@ def show_docs(options, docs=None):
sys.exit(0)
if options.get("--action", "") == "metadata":
- metadata(device_opt, options, docs)
+ metadata(device_opt, docs)
sys.exit(0)
if options.has_key("--version"):
diff --git a/fence/agents/ovh/Makefile.am b/fence/agents/ovh/Makefile.am
index f0d3f29..3793562 100644
--- a/fence/agents/ovh/Makefile.am
+++ b/fence/agents/ovh/Makefile.am
@@ -10,7 +10,7 @@ sbin_SCRIPTS = $(TARGET)
man_MANS = $(TARGET).8
-FENCE_TEST_ARGS = -l test -p test -n 1
+FENCE_TEST_ARGS = -l test -p test -n 1 --email test(a)test.te
include $(top_srcdir)/make/fencebuild.mk
include $(top_srcdir)/make/fenceman.mk
diff --git a/fence/agents/ovh/fence_ovh.py b/fence/agents/ovh/fence_ovh.py
index 55675db..3dfee49 100644
--- a/fence/agents/ovh/fence_ovh.py
+++ b/fence/agents/ovh/fence_ovh.py
@@ -32,7 +32,6 @@ def define_new_opts():
"help" : "-Z, --email=[email] email for reboot message: admin(a)domain.com",
"required" : "1",
"shortdesc" : "Reboot email",
- "default" : "",
"order" : 1}
def netboot_reboot(conn, options, mode):
diff --git a/tests/data/metadata/fence_cisco_ucs.xml b/tests/data/metadata/fence_cisco_ucs.xml
index 5e7f869..52ff1b1 100644
--- a/tests/data/metadata/fence_cisco_ucs.xml
+++ b/tests/data/metadata/fence_cisco_ucs.xml
@@ -70,7 +70,7 @@
</parameter>
<parameter name="suborg" unique="0" required="0">
<getopt mixed="--suborg=[path]" />
- <content type="string" />
+ <content type="string" default="" />
<shortdesc lang="en">Additional path needed to access suborganization</shortdesc>
</parameter>
<parameter name="verbose" unique="0" required="0">
9 years, 6 months
fence-agents: master - fence_emerson: New fence agent for Emerson's devices MPX and MPH2
by Marek Grác
Gitweb: http://git.fedorahosted.org/git/?p=fence-agents.git;a=commitdiff;h=64e405...
Commit: 64e405b09f024e59258d215a7127eea285d184d0
Parent: fa09cfcbb869c93518eacaeb2b37579eaa0eac2c
Author: Marek 'marx' Grac <mgrac(a)redhat.com>
AuthorDate: Thu Dec 4 23:01:10 2014 +0100
Committer: Marek 'marx' Grac <mgrac(a)redhat.com>
CommitterDate: Thu Dec 4 23:01:10 2014 +0100
fence_emerson: New fence agent for Emerson's devices MPX and MPH2
Thanks to Emerson Network Power
---
configure.ac | 1 +
fence/agents/emerson/Makefile.am | 17 ++++
fence/agents/emerson/fence_emerson.py | 67 +++++++++++++
tests/data/metadata/fence_emerson.xml | 165 +++++++++++++++++++++++++++++++++
4 files changed, 250 insertions(+), 0 deletions(-)
diff --git a/configure.ac b/configure.ac
index 3ce4b06..cbf9623 100644
--- a/configure.ac
+++ b/configure.ac
@@ -282,6 +282,7 @@ AC_CONFIG_FILES([Makefile
fence/agents/drac5/Makefile
fence/agents/dummy/Makefile
fence/agents/eaton_snmp/Makefile
+ fence/agents/emerson/Makefile
fence/agents/eps/Makefile
fence/agents/hpblade/Makefile
fence/agents/ibmblade/Makefile
diff --git a/fence/agents/emerson/Makefile.am b/fence/agents/emerson/Makefile.am
new file mode 100644
index 0000000..f7e5497
--- /dev/null
+++ b/fence/agents/emerson/Makefile.am
@@ -0,0 +1,17 @@
+MAINTAINERCLEANFILES = Makefile.in
+
+TARGET = fence_emerson
+
+SRC = $(TARGET).py
+
+EXTRA_DIST = $(SRC)
+
+sbin_SCRIPTS = $(TARGET)
+
+man_MANS = $(TARGET).8
+
+FENCE_TEST_ARGS = -l test -p test -a test -n 1
+
+include $(top_srcdir)/make/fencebuild.mk
+include $(top_srcdir)/make/fenceman.mk
+include $(top_srcdir)/make/agentpycheck.mk
diff --git a/fence/agents/emerson/fence_emerson.py b/fence/agents/emerson/fence_emerson.py
new file mode 100644
index 0000000..1ef911b
--- /dev/null
+++ b/fence/agents/emerson/fence_emerson.py
@@ -0,0 +1,67 @@
+#!/usr/bin/python -tt
+
+import sys
+import atexit
+sys.path.append("@FENCEAGENTSLIBDIR@")
+from fencing import *
+from fencing_snmp import FencingSnmp
+
+#BEGIN_VERSION_GENERATION
+RELEASE_VERSION="Emerson SNMP fence agent"
+REDHAT_COPYRIGHT=""
+BUILD_DATE=""
+#END_VERSION_GENERATION
+
+### CONSTANTS ###
+STATUSES_OID = ".1.3.6.1.4.1.476.1.42.3.8.50.20.1.95"
+CONTROL_OID = ".1.3.6.1.4.1.476.1.42.3.8.50.20.1.100"
+NAMES_OID = ".1.3.6.1.4.1.476.1.42.3.8.50.20.1.10"
+
+# Status constants returned as value from SNMP
+STATUS_DOWN = 1
+STATUS_UP = 2
+
+# Status constants to set as value to SNMP
+STATUS_SET_OFF = 0
+STATUS_SET_ON = 1
+
+def get_power_status(conn, options):
+ (_, status) = conn.get("%s.%s"% (STATUSES_OID, options["--plug"]))
+ return status == str(STATUS_UP) and "on" or "off"
+
+def set_power_status(conn, options):
+ conn.set("%s.%s" % (CONTROL_OID, options["--plug"]),
+ (options["--action"] == "on" and STATUS_SET_ON or STATUS_SET_OFF))
+
+def get_outlets_status(conn, _):
+ result = {}
+ res_outlet = conn.walk(STATUSES_OID, 30)
+
+ for outlet_info in res_outlet:
+ port_num = ".".join(outlet_info[0].split('.')[-3:])
+ port_alias = conn.get("%s.%s"% (NAMES_OID, port_num))[1]
+ port_status = (outlet_info[1] == str(STATUS_UP) and "on" or "off")
+ result[port_num] = (port_alias, port_status)
+ return result
+
+def main():
+ device_opt = ["ipaddr", "login", "passwd", "no_login", "no_password", \
+ "port", "snmp_version", "community"]
+
+ atexit.register(atexit_handler)
+
+ options = check_input(device_opt, process_input(device_opt))
+
+ docs = {}
+ docs["shortdesc"] = "Fence agent for Emerson over SNMP"
+ docs["longdesc"] = "fence_emerson is an I/O Fencing agent \
+ which can be used with MPX and MPH2 managed rack PDU."
+ docs["vendorurl"] = "http://www.emersonnetworkpower.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()
diff --git a/tests/data/metadata/fence_emerson.xml b/tests/data/metadata/fence_emerson.xml
new file mode 100644
index 0000000..3b49b56
--- /dev/null
+++ b/tests/data/metadata/fence_emerson.xml
@@ -0,0 +1,165 @@
+<?xml version="1.0" ?>
+<resource-agent name="fence_emerson" shortdesc="Fence agent for Emerson over SNMP" >
+<longdesc>fence_emerson is an I/O Fencing agent which can be used with MPX and MPH2 managed rack PDU.</longdesc>
+<vendor-url>http://www.emersonnetworkpower.com</vendor-url>
+<parameters>
+ <parameter name="action" unique="0" required="1">
+ <getopt mixed="-o, --action=[action]" />
+ <content type="string" default="reboot" />
+ <shortdesc lang="en">Fencing Action</shortdesc>
+ </parameter>
+ <parameter name="community" unique="0" required="0">
+ <getopt mixed="-c, --community=[community]" />
+ <content type="string" />
+ <shortdesc lang="en">Set the community string</shortdesc>
+ </parameter>
+ <parameter name="inet4_only" unique="0" required="0">
+ <getopt mixed="-4, --inet4-only" />
+ <content type="boolean" />
+ <shortdesc lang="en">Forces agent to use IPv4 addresses only</shortdesc>
+ </parameter>
+ <parameter name="inet6_only" unique="0" required="0">
+ <getopt mixed="-6, --inet6-only" />
+ <content type="boolean" />
+ <shortdesc lang="en">Forces agent to use IPv6 addresses only</shortdesc>
+ </parameter>
+ <parameter name="ipaddr" unique="0" required="1">
+ <getopt mixed="-a, --ip=[ip]" />
+ <content type="string" />
+ <shortdesc lang="en">IP Address or Hostname</shortdesc>
+ </parameter>
+ <parameter name="ipport" unique="0" required="0">
+ <getopt mixed="-u, --ipport=[port]" />
+ <content type="string" default="161" />
+ <shortdesc lang="en">TCP/UDP port to use for connection with device</shortdesc>
+ </parameter>
+ <parameter name="login" unique="0" required="0">
+ <getopt mixed="-l, --username=[name]" />
+ <content type="string" />
+ <shortdesc lang="en">Login Name</shortdesc>
+ </parameter>
+ <parameter name="passwd" unique="0" required="0">
+ <getopt mixed="-p, --password=[password]" />
+ <content type="string" />
+ <shortdesc lang="en">Login password or passphrase</shortdesc>
+ </parameter>
+ <parameter name="passwd_script" unique="0" required="0">
+ <getopt mixed="-S, --password-script=[script]" />
+ <content type="string" />
+ <shortdesc lang="en">Script to retrieve password</shortdesc>
+ </parameter>
+ <parameter name="port" unique="0" required="1">
+ <getopt mixed="-n, --plug=[id]" />
+ <content type="string" />
+ <shortdesc lang="en">Physical plug number, name of virtual machine or UUID</shortdesc>
+ </parameter>
+ <parameter name="snmp_auth_prot" unique="0" required="0">
+ <getopt mixed="-b, --snmp-auth-prot=[prot]" />
+ <content type="select" >
+ <option value="MD5" />
+ <option value="SHA" />
+ </content>
+ <shortdesc lang="en">Set authentication protocol (MD5|SHA)</shortdesc>
+ </parameter>
+ <parameter name="snmp_priv_passwd" unique="0" required="0">
+ <getopt mixed="-P, --snmp-priv-passwd=[pass]" />
+ <content type="string" />
+ <shortdesc lang="en">Set privacy protocol password</shortdesc>
+ </parameter>
+ <parameter name="snmp_priv_passwd_script" unique="0" required="0">
+ <getopt mixed="-R, --snmp-priv-passwd-script" />
+ <content type="string" />
+ <shortdesc lang="en">Script to run to retrieve privacy password</shortdesc>
+ </parameter>
+ <parameter name="snmp_priv_prot" unique="0" required="0">
+ <getopt mixed="-B, --snmp-priv-prot=[prot]" />
+ <content type="select" >
+ <option value="DES" />
+ <option value="AES" />
+ </content>
+ <shortdesc lang="en">Set privacy protocol (DES|AES)</shortdesc>
+ </parameter>
+ <parameter name="snmp_sec_level" unique="0" required="0">
+ <getopt mixed="-E, --snmp-sec-level=[level]" />
+ <content type="select" >
+ <option value="noAuthNoPriv" />
+ <option value="authNoPriv" />
+ <option value="authPriv" />
+ </content>
+ <shortdesc lang="en">Set security level (noAuthNoPriv|authNoPriv|authPriv)</shortdesc>
+ </parameter>
+ <parameter name="snmp_version" unique="0" required="0">
+ <getopt mixed="-d, --snmp-version=[version]" />
+ <content type="select" >
+ <option value="1" />
+ <option value="2c" />
+ <option value="3" />
+ </content>
+ <shortdesc lang="en">Specifies SNMP version to use (1,2c,3)</shortdesc>
+ </parameter>
+ <parameter name="verbose" unique="0" required="0">
+ <getopt mixed="-v, --verbose" />
+ <content type="boolean" />
+ <shortdesc lang="en">Verbose mode</shortdesc>
+ </parameter>
+ <parameter name="debug" unique="0" required="0">
+ <getopt mixed="-D, --debug-file=[debugfile]" />
+ <content type="string" />
+ <shortdesc lang="en">Write debug information to given file</shortdesc>
+ </parameter>
+ <parameter name="version" unique="0" required="0">
+ <getopt mixed="-V, --version" />
+ <content type="boolean" />
+ <shortdesc lang="en">Display version information and exit</shortdesc>
+ </parameter>
+ <parameter name="help" unique="0" required="0">
+ <getopt mixed="-h, --help" />
+ <content type="boolean" />
+ <shortdesc lang="en">Display help and exit</shortdesc>
+ </parameter>
+ <parameter name="separator" unique="0" required="0">
+ <getopt mixed="-C, --separator=[char]" />
+ <content type="string" default="," />
+ <shortdesc lang="en">Separator for CSV created by operation list</shortdesc>
+ </parameter>
+ <parameter name="delay" unique="0" required="0">
+ <getopt mixed="--delay=[seconds]" />
+ <content type="string" default="0" />
+ <shortdesc lang="en">Wait X seconds before fencing is started</shortdesc>
+ </parameter>
+ <parameter name="login_timeout" unique="0" required="0">
+ <getopt mixed="--login-timeout=[seconds]" />
+ <content type="string" default="5" />
+ <shortdesc lang="en">Wait X seconds for cmd prompt after login</shortdesc>
+ </parameter>
+ <parameter name="power_timeout" unique="0" required="0">
+ <getopt mixed="--power-timeout=[seconds]" />
+ <content type="string" default="20" />
+ <shortdesc lang="en">Test X seconds for status change after ON/OFF</shortdesc>
+ </parameter>
+ <parameter name="power_wait" unique="0" required="0">
+ <getopt mixed="--power-wait=[seconds]" />
+ <content type="string" default="0" />
+ <shortdesc lang="en">Wait X seconds after issuing ON/OFF</shortdesc>
+ </parameter>
+ <parameter name="shell_timeout" unique="0" required="0">
+ <getopt mixed="--shell-timeout=[seconds]" />
+ <content type="string" default="3" />
+ <shortdesc lang="en">Wait X seconds for cmd prompt after issuing command</shortdesc>
+ </parameter>
+ <parameter name="retry_on" unique="0" required="0">
+ <getopt mixed="--retry-on=[attempts]" />
+ <content type="string" default="1" />
+ <shortdesc lang="en">Count of attempts to retry power on</shortdesc>
+ </parameter>
+</parameters>
+<actions>
+ <action name="on" automatic="0"/>
+ <action name="off" />
+ <action name="reboot" />
+ <action name="status" />
+ <action name="list" />
+ <action name="monitor" />
+ <action name="metadata" />
+</actions>
+</resource-agent>
9 years, 6 months
fence-agents: master - fence_eps, fence_amt: Fix invalid default port values
by Marek Grác
Gitweb: http://git.fedorahosted.org/git/?p=fence-agents.git;a=commitdiff;h=fa09cf...
Commit: fa09cfcbb869c93518eacaeb2b37579eaa0eac2c
Parent: e51702932b482b8ded91a80d43f6f50e797a6373
Author: Marek 'marx' Grac <mgrac(a)redhat.com>
AuthorDate: Thu Dec 4 17:04:11 2014 +0100
Committer: Marek 'marx' Grac <mgrac(a)redhat.com>
CommitterDate: Thu Dec 4 23:00:36 2014 +0100
fence_eps, fence_amt: Fix invalid default port values
---
fence/agents/amt/fence_amt.py | 2 ++
fence/agents/eps/fence_eps.py | 2 +-
tests/data/metadata/fence_amt.xml | 2 +-
tests/data/metadata/fence_eps.xml | 2 +-
4 files changed, 5 insertions(+), 3 deletions(-)
diff --git a/fence/agents/amt/fence_amt.py b/fence/agents/amt/fence_amt.py
index 7027302..5ec785a 100644
--- a/fence/agents/amt/fence_amt.py
+++ b/fence/agents/amt/fence_amt.py
@@ -94,6 +94,8 @@ def main():
define_new_opts()
+ all_opt["ipport"]["default"] = "16994"
+
options = check_input(device_opt, process_input(device_opt))
docs = {}
diff --git a/fence/agents/eps/fence_eps.py b/fence/agents/eps/fence_eps.py
index 51f4758..9e31207 100644
--- a/fence/agents/eps/fence_eps.py
+++ b/fence/agents/eps/fence_eps.py
@@ -98,7 +98,7 @@ def eps_define_new_opts():
# Starting point of fence agent
def main():
device_opt = ["ipaddr", "login", "passwd", "no_login", "no_password", \
- "port", "hidden_page"]
+ "port", "hidden_page", "web"]
atexit.register(atexit_handler)
diff --git a/tests/data/metadata/fence_amt.xml b/tests/data/metadata/fence_amt.xml
index b7f6e93..2f50a4c 100644
--- a/tests/data/metadata/fence_amt.xml
+++ b/tests/data/metadata/fence_amt.xml
@@ -36,7 +36,7 @@
</parameter>
<parameter name="ipport" unique="0" required="0">
<getopt mixed="-u, --ipport=[port]" />
- <content type="string" default="23" />
+ <content type="string" default="16994" />
<shortdesc lang="en">TCP/UDP port to use for connection with device</shortdesc>
</parameter>
<parameter name="method" unique="0" required="0">
diff --git a/tests/data/metadata/fence_eps.xml b/tests/data/metadata/fence_eps.xml
index be4fed6..5f047cf 100644
--- a/tests/data/metadata/fence_eps.xml
+++ b/tests/data/metadata/fence_eps.xml
@@ -32,7 +32,7 @@ Agent basically works by connecting to hidden page and pass appropriate argument
</parameter>
<parameter name="ipport" unique="0" required="0">
<getopt mixed="-u, --ipport=[port]" />
- <content type="string" default="23" />
+ <content type="string" default="80" />
<shortdesc lang="en">TCP/UDP port to use for connection with device</shortdesc>
</parameter>
<parameter name="login" unique="0" required="0">
9 years, 6 months
fence-agents: master - [refactor] Function _update_metadata(..)
by Marek Grác
Gitweb: http://git.fedorahosted.org/git/?p=fence-agents.git;a=commitdiff;h=e51702...
Commit: e51702932b482b8ded91a80d43f6f50e797a6373
Parent: 850888570f2d7093efcb73d3e4a6f8d22dcb38c5
Author: Marek 'marx' Grac <mgrac(a)redhat.com>
AuthorDate: Thu Dec 4 16:26:13 2014 +0100
Committer: Marek 'marx' Grac <mgrac(a)redhat.com>
CommitterDate: Thu Dec 4 23:00:25 2014 +0100
[refactor] Function _update_metadata(..)
---
fence/agents/lib/fencing.py.py | 75 +++++++++++++++++++--------------------
1 files changed, 37 insertions(+), 38 deletions(-)
diff --git a/fence/agents/lib/fencing.py.py b/fence/agents/lib/fencing.py.py
index caef822..370e42f 100644
--- a/fence/agents/lib/fencing.py.py
+++ b/fence/agents/lib/fencing.py.py
@@ -1070,49 +1070,41 @@ def _update_metadata(options):
else:
all_opt["login"]["required"] = "0"
+ available_actions = ["status", "reboot", "off", "on"]
if device_opt.count("fabric_fencing"):
+ available_actions.remove("reboot")
all_opt["action"]["default"] = "off"
- if device_opt.count("no_status"):
- all_opt["action"]["help"] = "-o, --action=[action] Action: off (default) or on"
- else:
- all_opt["action"]["help"] = "-o, --action=[action] Action: status, off (default) or on"
- else:
- if device_opt.count("no_status"):
- all_opt["action"]["help"] = "-o, --action=[action] Action: reboot (default), off or on"
+ if device_opt.count("no_status"):
+ available_actions.remove("status")
+ actions_with_default = \
+ [x if not x == all_opt["action"]["default"] else x + " (default)" for x in available_actions]
+ all_opt["action"]["help"] = \
+ "-o, --action=[action] Action: %s" % (_join2(actions_with_default, last_separator=" or "))
if device_opt.count("ipport"):
- if options.has_key("--ipport"):
- all_opt["ipport"]["help"] = "-u, --ipport=[port] " + \
- "TCP/UDP port to use (default " + options["--ipport"] +")"
- elif all_opt.has_key("ipport") and all_opt["ipport"].has_key("default"):
- all_opt["ipport"]["help"] = "-u, --ipport=[port] " + \
- "TCP/UDP port to use (default " + all_opt["ipport"]["default"] +")"
- elif device_opt.count("snmp_version"):
- all_opt["ipport"]["default"] = "161"
- all_opt["ipport"]["help"] = "-u, --ipport=[port] TCP/UDP port to use (default 161)"
- elif options.has_key("--ssh") or \
- (all_opt["secure"].has_key("default") and all_opt["secure"]["default"] == '1'):
- all_opt["ipport"]["default"] = 22
- all_opt["ipport"]["help"] = "-u, --ipport=[port] TCP/UDP port to use (default 22)"
- elif options.has_key("--ssl") or options.has_key("--ssl-secure") or \
- options.has_key("--ssl-insecure") or \
- (all_opt["ssl"].has_key("default") and all_opt["ssl"]["default"] == '1'):
- all_opt["ipport"]["default"] = 443
- all_opt["ipport"]["help"] = "-u, --ipport=[port] TCP/UDP port to use (default 443)"
- elif device_opt.count("web"):
- all_opt["ipport"]["default"] = 80
- if device_opt.count("ssl") == 0:
- all_opt["ipport"]["help"] = "-u, --ipport=[port] TCP/UDP port to use (default 80)"
- else:
- all_opt["ipport"]["help"] = "-u, --ipport=[port] TCP/UDP port to use\n\
- (default 80, 443 if --ssl option is used)"
+ default_value = None
+ default_string = None
+
+ if all_opt["ipport"].has_key("default"):
+ default_value = all_opt["ipport"]["default"]
+ elif device_opt.count("web") and device_opt.count("ssl"):
+ default_value = "80"
+ default_string = "(default 80, 443 if --ssl option is used)"
+ elif device_opt.count("telnet") and device_opt.count("secure"):
+ default_value = "23"
+ default_string = "(default 23, 22 if --ssh option is used)"
else:
- all_opt["ipport"]["default"] = 23
- if device_opt.count("secure") == 0:
- all_opt["ipport"]["help"] = "-u, --ipport=[port] TCP/UDP port to use (default 23)"
- else:
- all_opt["ipport"]["help"] = "-u, --ipport=[port] TCP/UDP port to use\n\
- (default 23, 22 if --ssh option is used)"
+ tcp_ports = {"snmp_version" : "161", "secure" : "22", "telnet" : "23", "web" : "80", "ssl" : "443"}
+ # all cases where next command returns multiple results are covered by previous blocks
+ protocol = [x for x in ["snmp_version", "secure", "ssl", "web", "telnet"] if device_opt.count(x)][0]
+ default_value = tcp_ports[protocol]
+
+ all_opt["ipport"]["default"] = default_value
+ if default_string is None:
+ all_opt["ipport"]["help"] = "-u, --ipport=[port] TCP/UDP port to use (default %s)" % \
+ (default_value)
+ else:
+ all_opt["ipport"]["help"] = "-u, --ipport=[port] TCP/UDP port to use\n" + " "*40 + default_string
def _set_default_values(options):
for opt in options["device_opt"]:
@@ -1236,3 +1228,10 @@ def _parse_input_cmdline(avail_opt):
opt["--" + all_opt[x]["longopt"]] = dict(entered_opt)[o]
opt[o] = dict(entered_opt)[o]
return opt
+
+# for ["John", "Mary", "Eli"] returns "John, Mary and Eli"
+def _join2(words, normal_separator=", ", last_separator=" and "):
+ if len(words) <= 1:
+ return "".join(words)
+ else:
+ return last_separator.join([normal_separator.join(words[:-1]), words[-1]])
9 years, 6 months
fence-agents: master - [refactor] function process_input(..)
by Marek Grác
Gitweb: http://git.fedorahosted.org/git/?p=fence-agents.git;a=commitdiff;h=850888...
Commit: 850888570f2d7093efcb73d3e4a6f8d22dcb38c5
Parent: f1662bf0e0508cae1a34b414580f0db896aa8162
Author: Marek 'marx' Grac <mgrac(a)redhat.com>
AuthorDate: Thu Dec 4 15:18:25 2014 +0100
Committer: Marek 'marx' Grac <mgrac(a)redhat.com>
CommitterDate: Thu Dec 4 23:00:20 2014 +0100
[refactor] function process_input(..)
---
fence/agents/lib/fencing.py.py | 147 +++++++++++++++++++---------------------
1 files changed, 71 insertions(+), 76 deletions(-)
diff --git a/fence/agents/lib/fencing.py.py b/fence/agents/lib/fencing.py.py
index 83ce41a..caef822 100644
--- a/fence/agents/lib/fencing.py.py
+++ b/fence/agents/lib/fencing.py.py
@@ -465,7 +465,7 @@ def atexit_handler():
logging.error("%s failed to close standard output\n", sys.argv[0])
sys.exit(EC_GENERIC_ERROR)
-def add_dependency_options(options):
+def _add_dependency_options(options):
## Add also options which are available for every fence agent
added_opt = []
for opt in options + ["default"]:
@@ -575,86 +575,16 @@ def metadata(avail_opt, options, docs):
print "</resource-agent>"
def process_input(avail_opt):
- avail_opt.extend(add_dependency_options(avail_opt))
+ avail_opt.extend(_add_dependency_options(avail_opt))
- ##
- ## Set standard environment
- #####
+ # @todo: this should be put elsewhere?
os.putenv("LANG", "C")
os.putenv("LC_ALL", "C")
- ##
- ## Prepare list of options for getopt
- #####
- getopt_string = ""
- longopt_list = []
- for k in avail_opt:
- if all_opt.has_key(k) and all_opt[k]["getopt"] != ":":
- # getopt == ":" means that opt is without short getopt, but has value
- getopt_string += all_opt[k]["getopt"]
- elif not all_opt.has_key(k):
- fail_usage("Parse error: unknown option '"+k+"'")
-
- if all_opt.has_key(k) and all_opt[k].has_key("longopt"):
- if all_opt[k]["getopt"].endswith(":"):
- longopt_list.append(all_opt[k]["longopt"] + "=")
- else:
- longopt_list.append(all_opt[k]["longopt"])
-
- ##
- ## Read options from command line or standard input
- #####
if len(sys.argv) > 1:
- try:
- entered_opt = getopt.gnu_getopt(sys.argv[1:], getopt_string, longopt_list)[0]
- except getopt.GetoptError, error:
- fail_usage("Parse error: " + error.msg)
-
- ## Transform short getopt to long one which are used in fencing agents
- #####
- opt = {}
- for o in dict(entered_opt).keys():
- if o.startswith("--"):
- for x in all_opt.keys():
- if all_opt[x].has_key("longopt") and "--" + all_opt[x]["longopt"] == o:
- opt["--" + all_opt[x]["longopt"]] = dict(entered_opt)[o]
- else:
- for x in all_opt.keys():
- if x in avail_opt and all_opt[x].has_key("getopt") and all_opt[x].has_key("longopt") and \
- ("-" + all_opt[x]["getopt"] == o or "-" + all_opt[x]["getopt"].rstrip(":") == o):
- opt["--" + all_opt[x]["longopt"]] = dict(entered_opt)[o]
- opt[o] = dict(entered_opt)[o]
-
- ## Compatibility Layer
- #####
- z = dict(opt)
- if z.has_key("--plug"):
- z["-m"] = z["--plug"]
-
- opt = z
- ##
- #####
+ opt = _parse_input_cmdline(avail_opt)
else:
- opt = {}
- name = ""
- for line in sys.stdin.readlines():
- line = line.strip()
- if (line.startswith("#")) or (len(line) == 0):
- continue
-
- (name, value) = (line + "=").split("=", 1)
- value = value[:-1]
-
- if avail_opt.count(name) == 0 and name in ["nodename"]:
- continue
- elif avail_opt.count(name) == 0:
- logging.warning("Parse error: Ignoring unknown option '%s'\n", line)
- continue
-
- if all_opt[name]["getopt"].endswith(":"):
- opt["--"+all_opt[name]["longopt"].rstrip(":")] = value
- elif value.lower() in ["1", "yes", "on", "true"]:
- opt["--"+all_opt[name]["longopt"]] = "1"
+ opt = _parse_input_stdin(avail_opt)
return opt
##
@@ -663,7 +593,7 @@ def process_input(avail_opt):
## password script to set a correct password
######
def check_input(device_opt, opt):
- device_opt.extend(add_dependency_options(device_opt))
+ device_opt.extend(_add_dependency_options(device_opt))
options = dict(opt)
options["device_opt"] = device_opt
@@ -1241,3 +1171,68 @@ def _validate_input(options):
def _encode_html_entities(text):
return text.replace("&", "&").replace('"', """).replace('<', "<"). \
replace('>', ">").replace("'", "'")
+
+def _prepare_getopt_args(options):
+ getopt_string = ""
+ longopt_list = []
+ for k in options:
+ if all_opt.has_key(k) and all_opt[k]["getopt"] != ":":
+ # getopt == ":" means that opt is without short getopt, but has value
+ getopt_string += all_opt[k]["getopt"]
+ elif not all_opt.has_key(k):
+ fail_usage("Parse error: unknown option '"+k+"'")
+
+ if all_opt.has_key(k) and all_opt[k].has_key("longopt"):
+ if all_opt[k]["getopt"].endswith(":"):
+ longopt_list.append(all_opt[k]["longopt"] + "=")
+ else:
+ longopt_list.append(all_opt[k]["longopt"])
+
+ return (getopt_string, longopt_list)
+
+def _parse_input_stdin(avail_opt):
+ opt = {}
+ name = ""
+ for line in sys.stdin.readlines():
+ line = line.strip()
+ if (line.startswith("#")) or (len(line) == 0):
+ continue
+
+ (name, value) = (line + "=").split("=", 1)
+ value = value[:-1]
+
+ if avail_opt.count(name) == 0 and name in ["nodename"]:
+ continue
+ elif avail_opt.count(name) == 0:
+ logging.warning("Parse error: Ignoring unknown option '%s'\n", line)
+ continue
+
+ if all_opt[name]["getopt"].endswith(":"):
+ opt["--"+all_opt[name]["longopt"].rstrip(":")] = value
+ elif value.lower() in ["1", "yes", "on", "true"]:
+ opt["--"+all_opt[name]["longopt"]] = "1"
+ return opt
+
+def _parse_input_cmdline(avail_opt):
+ (getopt_string, longopt_list) = _prepare_getopt_args(avail_opt)
+
+ try:
+ entered_opt = getopt.gnu_getopt(sys.argv[1:], getopt_string, longopt_list)[0]
+ except getopt.GetoptError, error:
+ fail_usage("Parse error: " + error.msg)
+
+ ## Transform short getopt to long one which are used in fencing agents
+ #####
+ opt = {}
+ for o in dict(entered_opt).keys():
+ if o.startswith("--"):
+ for x in all_opt.keys():
+ if all_opt[x].has_key("longopt") and "--" + all_opt[x]["longopt"] == o:
+ opt["--" + all_opt[x]["longopt"]] = dict(entered_opt)[o]
+ else:
+ for x in all_opt.keys():
+ if x in avail_opt and all_opt[x].has_key("getopt") and all_opt[x].has_key("longopt") and \
+ ("-" + all_opt[x]["getopt"] == o or "-" + all_opt[x]["getopt"].rstrip(":") == o):
+ opt["--" + all_opt[x]["longopt"]] = dict(entered_opt)[o]
+ opt[o] = dict(entered_opt)[o]
+ return opt
9 years, 6 months
fence-agents: master - [refactor] function metadata(..)
by Marek Grác
Gitweb: http://git.fedorahosted.org/git/?p=fence-agents.git;a=commitdiff;h=f1662b...
Commit: f1662bf0e0508cae1a34b414580f0db896aa8162
Parent: a4c92e3dd9809a486f6231a96e0be7c45266231e
Author: Marek 'marx' Grac <mgrac(a)redhat.com>
AuthorDate: Wed Dec 3 19:53:01 2014 +0100
Committer: Marek 'marx' Grac <mgrac(a)redhat.com>
CommitterDate: Thu Dec 4 23:00:09 2014 +0100
[refactor] function metadata(..)
---
fence/agents/lib/fencing.py.py | 38 ++++++++++--------------------------
fence/agents/netio/fence_netio.py | 7 +----
fence/agents/rsb/fence_rsb.py | 5 ++-
3 files changed, 16 insertions(+), 34 deletions(-)
diff --git a/fence/agents/lib/fencing.py.py b/fence/agents/lib/fencing.py.py
index fc0b55c..83ce41a 100644
--- a/fence/agents/lib/fencing.py.py
+++ b/fence/agents/lib/fencing.py.py
@@ -516,9 +516,8 @@ def metadata(avail_opt, options, docs):
print "<?xml version=\"1.0\" ?>"
print "<resource-agent name=\"" + os.path.basename(sys.argv[0]) + \
"\" shortdesc=\"" + docs["shortdesc"] + "\" >"
- if "symlink" in docs:
- for (symlink, desc) in docs["symlink"]:
- print "<symlink name=\"" + symlink + "\" shortdesc=\"" + desc + "\"/>"
+ for (symlink, desc) in docs.get("symlink", []):
+ print "<symlink name=\"" + symlink + "\" shortdesc=\"" + desc + "\"/>"
print "<longdesc>" + docs["longdesc"] + "</longdesc>"
if docs.has_key("vendorurl"):
print "<vendor-url>" + docs["vendorurl"] + "</vendor-url>"
@@ -530,30 +529,18 @@ def metadata(avail_opt, options, docs):
default = ""
if all_opt[option].has_key("default"):
default = str(all_opt[option]["default"])
- elif options.has_key("--" + all_opt[option]["longopt"]) and all_opt[option]["getopt"].endswith(":"):
- if options["--" + all_opt[option]["longopt"]]:
- try:
- default = options["--" + all_opt[option]["longopt"]]
- except TypeError:
- ## @todo/@note: Currently there is no clean way how to handle lists
- ## we can create a string from it but we can't set it on command line
- default = str(options["--" + all_opt[option]["longopt"]])
elif options.has_key("--" + all_opt[option]["longopt"]):
default = "true"
if default:
- default = default.replace("&", "&")
- default = default.replace('"', """)
- default = default.replace('<', "<")
- default = default.replace('>', ">")
- default = default.replace("'", "'")
- default = "default=\"" + default + "\" "
+ default = "default=\"" + _encode_html_entities(default) + "\" "
mixed = all_opt[option]["help"]
## split it between option and help text
res = re.compile(r"^(.*?--\S+)\s+", re.IGNORECASE | re.S).search(mixed)
if None != res:
mixed = res.group(1)
+ # @todo: replace with _encode_html_entities but update XML metadata in regression tests
mixed = mixed.replace("<", "<").replace(">", ">")
print "\t\t<getopt mixed=\"" + mixed + "\" />"
@@ -571,14 +558,9 @@ def metadata(avail_opt, options, docs):
print "\t</parameter>"
print "</parameters>"
print "<actions>"
- if avail_opt.count("fabric_fencing") == 1:
- ## do 'unfence' at the start
- if avail_opt.count("on_target") == 1:
- print "\t<action name=\"on\" on_target=\"1\" automatic=\"1\"/>"
- else:
- print "\t<action name=\"on\" automatic=\"1\"/>"
- else:
- print "\t<action name=\"on\" automatic=\"0\"/>"
+
+ on_target = ' on_target="1"' if avail_opt.count("on_target") else ''
+ print "\t<action name=\"on\"%s automatic=\"%d\"/>" % (on_target, avail_opt.count("fabric_fencing"))
print "\t<action name=\"off\" />"
if avail_opt.count("fabric_fencing") == 0:
@@ -796,8 +778,6 @@ def show_docs(options, docs=None):
docs["shortdesc"] = "Fence agent"
docs["longdesc"] = ""
- ## Process special options (and exit)
- #####
if options.has_key("--help"):
usage(device_opt)
sys.exit(0)
@@ -1257,3 +1237,7 @@ def _validate_input(options):
"for %s from the valid values: %s" % \
("--" + all_opt[opt]["longopt"], str(all_opt[opt]["choices"])))
+
+def _encode_html_entities(text):
+ return text.replace("&", "&").replace('"', """).replace('<', "<"). \
+ replace('>', ">").replace("'", "'")
diff --git a/fence/agents/netio/fence_netio.py b/fence/agents/netio/fence_netio.py
index 1a37206..7b67e15 100755
--- a/fence/agents/netio/fence_netio.py
+++ b/fence/agents/netio/fence_netio.py
@@ -57,12 +57,9 @@ def main():
atexit.register(atexit_handler)
- opt = process_input(device_opt)
-
- # set default port for telnet only
- if not opt.has_key("--ipport"):
- opt["--ipport"] = "1234"
+ all_opt["ipport"]["default"] = "1234"
+ opt = process_input(device_opt)
opt["eol"] = "\r\n"
options = check_input(device_opt, opt)
diff --git a/fence/agents/rsb/fence_rsb.py b/fence/agents/rsb/fence_rsb.py
index 73941b6..2ee85fe 100755
--- a/fence/agents/rsb/fence_rsb.py
+++ b/fence/agents/rsb/fence_rsb.py
@@ -47,9 +47,10 @@ def main():
opt = process_input(device_opt)
- # set default port for telnet only
if not opt.has_key("--ssh") and not opt.has_key("--ipport"):
- opt["--ipport"] = "3172"
+ # set default value like it should be set as usually
+ all_opt["ipport"]["default"] = "3172"
+ opt["--ipport"] = all_opt["ipport"]["default"]
options = check_input(device_opt, opt)
9 years, 6 months
fence-agents: master - [refactor] function check_input(..)
by Marek Grác
Gitweb: http://git.fedorahosted.org/git/?p=fence-agents.git;a=commitdiff;h=a4c92e...
Commit: a4c92e3dd9809a486f6231a96e0be7c45266231e
Parent: a6970761f865f820ff4924e414ff4e335b6c3a74
Author: Marek 'marx' Grac <mgrac(a)redhat.com>
AuthorDate: Wed Dec 3 19:03:39 2014 +0100
Committer: Marek 'marx' Grac <mgrac(a)redhat.com>
CommitterDate: Thu Dec 4 22:59:56 2014 +0100
[refactor] function check_input(..)
---
fence/agents/lib/fencing.py.py | 222 +++++++++++++++++++++-------------------
1 files changed, 115 insertions(+), 107 deletions(-)
diff --git a/fence/agents/lib/fencing.py.py b/fence/agents/lib/fencing.py.py
index 0ff1f52..fc0b55c 100644
--- a/fence/agents/lib/fencing.py.py
+++ b/fence/agents/lib/fencing.py.py
@@ -686,72 +686,13 @@ def check_input(device_opt, opt):
options = dict(opt)
options["device_opt"] = device_opt
- ## Set requirements that should be included in metadata
- #####
- if device_opt.count("login") and device_opt.count("no_login") == 0:
- all_opt["login"]["required"] = "1"
- else:
- all_opt["login"]["required"] = "0"
-
- if device_opt.count("fabric_fencing"):
- all_opt["action"]["default"] = "off"
- if device_opt.count("no_status"):
- all_opt["action"]["help"] = "-o, --action=[action] Action: off (default) or on"
- else:
- all_opt["action"]["help"] = "-o, --action=[action] Action: status, off (default) or on"
- else:
- if device_opt.count("no_status"):
- all_opt["action"]["help"] = "-o, --action=[action] Action: reboot (default), off or on"
-
-
- if device_opt.count("ipport"):
- if options.has_key("--ipport"):
- all_opt["ipport"]["help"] = "-u, --ipport=[port] " + \
- "TCP/UDP port to use (default " + options["--ipport"] +")"
- elif all_opt.has_key("ipport") and all_opt["ipport"].has_key("default"):
- all_opt["ipport"]["help"] = "-u, --ipport=[port] " + \
- "TCP/UDP port to use (default " + all_opt["ipport"]["default"] +")"
- elif device_opt.count("snmp_version"):
- all_opt["ipport"]["default"] = "161"
- all_opt["ipport"]["help"] = "-u, --ipport=[port] TCP/UDP port to use (default 161)"
- elif options.has_key("--ssh") or \
- (all_opt["secure"].has_key("default") and all_opt["secure"]["default"] == '1'):
- all_opt["ipport"]["default"] = 22
- all_opt["ipport"]["help"] = "-u, --ipport=[port] TCP/UDP port to use (default 22)"
- elif options.has_key("--ssl") or options.has_key("--ssl-secure") or \
- options.has_key("--ssl-insecure") or \
- (all_opt["ssl"].has_key("default") and all_opt["ssl"]["default"] == '1'):
- all_opt["ipport"]["default"] = 443
- all_opt["ipport"]["help"] = "-u, --ipport=[port] TCP/UDP port to use (default 443)"
- elif device_opt.count("web"):
- all_opt["ipport"]["default"] = 80
- if device_opt.count("ssl") == 0:
- all_opt["ipport"]["help"] = "-u, --ipport=[port] TCP/UDP port to use (default 80)"
- else:
- all_opt["ipport"]["help"] = "-u, --ipport=[port] TCP/UDP port to use\n\
- (default 80, 443 if --ssl option is used)"
- else:
- all_opt["ipport"]["default"] = 23
- if device_opt.count("secure") == 0:
- all_opt["ipport"]["help"] = "-u, --ipport=[port] TCP/UDP port to use (default 23)"
- else:
- all_opt["ipport"]["help"] = "-u, --ipport=[port] TCP/UDP port to use\n\
- (default 23, 22 if --ssh option is used)"
-
- ## Set default values
- #####
- for opt in device_opt:
- if all_opt[opt].has_key("default"):
- getopt_long = "--" + all_opt[opt]["longopt"]
- if not options.has_key(getopt_long):
- options[getopt_long] = all_opt[opt]["default"]
-
+ _update_metadata(options)
+ options = _set_default_values(options)
options["--action"] = options["--action"].lower()
## In special cases (show help, metadata or version) we don't need to check anything
#####
- if options.has_key("--help") or options.has_key("--version") or \
- options["--action"] == "metadata":
+ if options["--action"] == "metadata" or any(options.has_key(k) for k in ("--help", "--version")):
return options
if options.has_key("--verbose"):
@@ -759,7 +700,7 @@ def check_input(device_opt, opt):
## add logging to syslog
logging.getLogger().addHandler(SyslogLibHandler())
- ## add loggint to stderr
+ ## add logging to stderr
logging.getLogger().addHandler(logging.StreamHandler(stream=sys.stderr))
acceptable_actions = ["on", "off", "status", "list", "monitor"]
@@ -783,36 +724,7 @@ def check_input(device_opt, opt):
if options["--action"] == "disable":
options["--action"] = "off"
- ## automatic detection and set of valid UUID from --plug
- if not options.has_key("--username") and \
- device_opt.count("login") and (device_opt.count("no_login") == 0):
- fail_usage("Failed: You have to set login name")
-
- if device_opt.count("ipaddr") and not options.has_key("--ip") and not options.has_key("--managed"):
- fail_usage("Failed: You have to enter fence address")
-
- if device_opt.count("no_password") == 0:
- if 0 == device_opt.count("identity_file"):
- if not (options.has_key("--password") or options.has_key("--password-script")):
- fail_usage("Failed: You have to enter password or password script")
- else:
- if not (options.has_key("--password") or \
- options.has_key("--password-script") or options.has_key("--identity-file")):
- fail_usage("Failed: You have to enter password, password script or identity file")
-
- if not options.has_key("--ssh") and options.has_key("--identity-file"):
- fail_usage("Failed: You have to use identity file together with ssh connection (-x)")
-
- if options.has_key("--identity-file"):
- if not os.path.isfile(options["--identity-file"]):
- fail_usage("Failed: Identity file " + options["--identity-file"] + " does not exist")
-
- if (0 == ["list", "monitor"].count(options["--action"])) and \
- not options.has_key("--plug") and device_opt.count("port") and device_opt.count("no_port") == 0:
- fail_usage("Failed: You have to enter plug number or machine identification")
-
- if options.has_key("--password-script"):
- options["--password"] = os.popen(options["--password-script"]).read().rstrip()
+ _validate_input(options)
if options.has_key("--debug-file"):
try:
@@ -826,20 +738,8 @@ def check_input(device_opt, opt):
if options.has_key("--snmp-priv-passwd-script"):
options["--snmp-priv-passwd"] = os.popen(options["--snmp-priv-passwd-script"]).read().rstrip()
- if options.has_key("--plug") and len(options["--plug"].split(",")) > 1 and \
- options.has_key("--method") and options["--method"] == "cycle":
- fail_usage("Failed: Cannot use --method cycle for more than 1 plug")
-
- for opt in device_opt:
- if all_opt[opt].has_key("choices"):
- longopt = "--" + all_opt[opt]["longopt"]
- possible_values_upper = [y.upper() for y in all_opt[opt]["choices"]]
- if options.has_key(longopt):
- options[longopt] = options[longopt].upper()
- if not options["--" + all_opt[opt]["longopt"]] in possible_values_upper:
- fail_usage("Failed: You have to enter a valid choice " + \
- "for %s from the valid values: %s" % \
- ("--" + all_opt[opt]["longopt"], str(all_opt[opt]["choices"])))
+ if options.has_key("--password-script"):
+ options["--password"] = os.popen(options["--password-script"]).read().rstrip()
return options
@@ -1249,3 +1149,111 @@ def _login_ssh_with_password(options, re_login_string):
conn.log_expect(options["--command-prompt"], int(options["--login-timeout"]))
return conn
+
+#
+# To update metadata, we change values in all_opt
+def _update_metadata(options):
+ device_opt = options["device_opt"]
+
+ if device_opt.count("login") and device_opt.count("no_login") == 0:
+ all_opt["login"]["required"] = "1"
+ else:
+ all_opt["login"]["required"] = "0"
+
+ if device_opt.count("fabric_fencing"):
+ all_opt["action"]["default"] = "off"
+ if device_opt.count("no_status"):
+ all_opt["action"]["help"] = "-o, --action=[action] Action: off (default) or on"
+ else:
+ all_opt["action"]["help"] = "-o, --action=[action] Action: status, off (default) or on"
+ else:
+ if device_opt.count("no_status"):
+ all_opt["action"]["help"] = "-o, --action=[action] Action: reboot (default), off or on"
+
+ if device_opt.count("ipport"):
+ if options.has_key("--ipport"):
+ all_opt["ipport"]["help"] = "-u, --ipport=[port] " + \
+ "TCP/UDP port to use (default " + options["--ipport"] +")"
+ elif all_opt.has_key("ipport") and all_opt["ipport"].has_key("default"):
+ all_opt["ipport"]["help"] = "-u, --ipport=[port] " + \
+ "TCP/UDP port to use (default " + all_opt["ipport"]["default"] +")"
+ elif device_opt.count("snmp_version"):
+ all_opt["ipport"]["default"] = "161"
+ all_opt["ipport"]["help"] = "-u, --ipport=[port] TCP/UDP port to use (default 161)"
+ elif options.has_key("--ssh") or \
+ (all_opt["secure"].has_key("default") and all_opt["secure"]["default"] == '1'):
+ all_opt["ipport"]["default"] = 22
+ all_opt["ipport"]["help"] = "-u, --ipport=[port] TCP/UDP port to use (default 22)"
+ elif options.has_key("--ssl") or options.has_key("--ssl-secure") or \
+ options.has_key("--ssl-insecure") or \
+ (all_opt["ssl"].has_key("default") and all_opt["ssl"]["default"] == '1'):
+ all_opt["ipport"]["default"] = 443
+ all_opt["ipport"]["help"] = "-u, --ipport=[port] TCP/UDP port to use (default 443)"
+ elif device_opt.count("web"):
+ all_opt["ipport"]["default"] = 80
+ if device_opt.count("ssl") == 0:
+ all_opt["ipport"]["help"] = "-u, --ipport=[port] TCP/UDP port to use (default 80)"
+ else:
+ all_opt["ipport"]["help"] = "-u, --ipport=[port] TCP/UDP port to use\n\
+ (default 80, 443 if --ssl option is used)"
+ else:
+ all_opt["ipport"]["default"] = 23
+ if device_opt.count("secure") == 0:
+ all_opt["ipport"]["help"] = "-u, --ipport=[port] TCP/UDP port to use (default 23)"
+ else:
+ all_opt["ipport"]["help"] = "-u, --ipport=[port] TCP/UDP port to use\n\
+ (default 23, 22 if --ssh option is used)"
+
+def _set_default_values(options):
+ for opt in options["device_opt"]:
+ if all_opt[opt].has_key("default"):
+ getopt_long = "--" + all_opt[opt]["longopt"]
+ if not options.has_key(getopt_long):
+ options[getopt_long] = all_opt[opt]["default"]
+
+ return options
+
+def _validate_input(options):
+ device_opt = options["device_opt"]
+
+ if not options.has_key("--username") and \
+ device_opt.count("login") and (device_opt.count("no_login") == 0):
+ fail_usage("Failed: You have to set login name")
+
+ if device_opt.count("ipaddr") and not options.has_key("--ip") and not options.has_key("--managed"):
+ fail_usage("Failed: You have to enter fence address")
+
+ if device_opt.count("no_password") == 0:
+ if 0 == device_opt.count("identity_file"):
+ if not (options.has_key("--password") or options.has_key("--password-script")):
+ fail_usage("Failed: You have to enter password or password script")
+ else:
+ if not (options.has_key("--password") or \
+ options.has_key("--password-script") or options.has_key("--identity-file")):
+ fail_usage("Failed: You have to enter password, password script or identity file")
+
+ if not options.has_key("--ssh") and options.has_key("--identity-file"):
+ fail_usage("Failed: You have to use identity file together with ssh connection (-x)")
+
+ if options.has_key("--identity-file") and not os.path.isfile(options["--identity-file"]):
+ fail_usage("Failed: Identity file " + options["--identity-file"] + " does not exist")
+
+ if (0 == ["list", "monitor"].count(options["--action"])) and \
+ not options.has_key("--plug") and device_opt.count("port") and device_opt.count("no_port") == 0:
+ fail_usage("Failed: You have to enter plug number or machine identification")
+
+ if options.has_key("--plug") and len(options["--plug"].split(",")) > 1 and \
+ options.has_key("--method") and options["--method"] == "cycle":
+ fail_usage("Failed: Cannot use --method cycle for more than 1 plug")
+
+ for opt in device_opt:
+ if all_opt[opt].has_key("choices"):
+ longopt = "--" + all_opt[opt]["longopt"]
+ possible_values_upper = [y.upper() for y in all_opt[opt]["choices"]]
+ if options.has_key(longopt):
+ options[longopt] = options[longopt].upper()
+ if not options["--" + all_opt[opt]["longopt"]] in possible_values_upper:
+ fail_usage("Failed: You have to enter a valid choice " + \
+ "for %s from the valid values: %s" % \
+ ("--" + all_opt[opt]["longopt"], str(all_opt[opt]["choices"])))
+
9 years, 6 months
fence-agents: master - [refactor] Functionality of fence_login(...) was too broad
by Marek Grác
Gitweb: http://git.fedorahosted.org/git/?p=fence-agents.git;a=commitdiff;h=a69707...
Commit: a6970761f865f820ff4924e414ff4e335b6c3a74
Parent: e8b58b335409f4d576a114a7bf5f6ed69065c72f
Author: Marek 'marx' Grac <mgrac(a)redhat.com>
AuthorDate: Wed Dec 3 16:58:20 2014 +0100
Committer: Marek 'marx' Grac <mgrac(a)redhat.com>
CommitterDate: Thu Dec 4 22:59:42 2014 +0100
[refactor] Functionality of fence_login(...) was too broad
New 'private' functions were created for opening ssl connection, telnet,
ssh with password and ssh with identity file
---
fence/agents/lib/fencing.py.py | 258 ++++++++++++++++++++++------------------
1 files changed, 143 insertions(+), 115 deletions(-)
diff --git a/fence/agents/lib/fencing.py.py b/fence/agents/lib/fencing.py.py
index b060de2..0ff1f52 100644
--- a/fence/agents/lib/fencing.py.py
+++ b/fence/agents/lib/fencing.py.py
@@ -1006,13 +1006,7 @@ def fence_action(connection, options, set_power_fn, get_power_fn, get_outlet_lis
return result
def fence_login(options, re_login_string=r"(login\s*: )|((?!Last )Login Name: )|(username: )|(User Name :)"):
- force_ipvx = ""
-
- if options.has_key("--inet6-only"):
- force_ipvx = "-6 "
-
- if options.has_key("--inet4-only"):
- force_ipvx = "-4 "
+ run_delay(options)
if not options.has_key("eol"):
options["eol"] = "\r\n"
@@ -1020,119 +1014,15 @@ def fence_login(options, re_login_string=r"(login\s*: )|((?!Last )Login Name: )
if options.has_key("--command-prompt") and type(options["--command-prompt"]) is not list:
options["--command-prompt"] = [options["--command-prompt"]]
- ## Do the delay of the fence device before logging in
- run_delay(options)
-
try:
- re_login = re.compile(re_login_string, re.IGNORECASE)
- re_pass = re.compile("(password)|(pass phrase)", re.IGNORECASE)
-
if options.has_key("--ssl"):
- gnutls_opts = ""
- ssl_opts = ""
-
- if options.has_key("--notls"):
- gnutls_opts = "--priority \"NORMAL:-VERS-TLS1.2:-VERS-TLS1.1:-VERS-TLS1.0:+VERS-SSL3.0\""
-
- # --ssl is same as the --ssl-secure
- if options.has_key("--ssl-insecure"):
- ssl_opts = "--insecure"
-
- command = '%s %s %s --crlf -p %s %s' % \
- (options["--gnutlscli-path"], gnutls_opts, ssl_opts, options["--ipport"], options["--ip"])
- try:
- conn = fspawn(options, command)
- except pexpect.ExceptionPexpect, ex:
- logging.error("%s\n", str(ex))
- sys.exit(EC_GENERIC_ERROR)
+ conn = _open_ssl_connection(options)
elif options.has_key("--ssh") and not options.has_key("--identity-file"):
- command = '%s %s %s@%s -p %s -o PubkeyAuthentication=no' % \
- (options["--ssh-path"], force_ipvx, options["--username"], options["--ip"], options["--ipport"])
- if options.has_key("--ssh-options"):
- command += ' ' + options["--ssh-options"]
-
- conn = fspawn(options, command)
-
- if options.has_key("telnet_over_ssh"):
- # This is for stupid ssh servers (like ALOM) which behave more like telnet
- # (ignore name and display login prompt)
- result = conn.log_expect( \
- [re_login, "Are you sure you want to continue connecting (yes/no)?"],
- int(options["--login-timeout"]))
- if result == 1:
- conn.sendline("yes") # Host identity confirm
- conn.log_expect(re_login, int(options["--login-timeout"]))
-
- conn.sendline(options["--username"])
- conn.log_expect(re_pass, int(options["--login-timeout"]))
- else:
- result = conn.log_expect( \
- ["ssword:", "Are you sure you want to continue connecting (yes/no)?"],
- int(options["--login-timeout"]))
- if result == 1:
- conn.sendline("yes")
- conn.log_expect("ssword:", int(options["--login-timeout"]))
-
- conn.sendline(options["--password"])
- conn.log_expect(options["--command-prompt"], int(options["--login-timeout"]))
+ conn = _login_ssh_with_password(options, re_login_string)
elif options.has_key("--ssh") and options.has_key("--identity-file"):
- command = '%s %s %s@%s -i %s -p %s' % \
- (options["--ssh-path"], force_ipvx, options["--username"], options["--ip"], \
- options["--identity-file"], options["--ipport"])
- if options.has_key("--ssh-options"):
- command += ' ' + options["--ssh-options"]
-
- conn = fspawn(options, command)
-
- result = conn.log_expect(["Enter passphrase for key '" + options["--identity-file"] + "':", \
- "Are you sure you want to continue connecting (yes/no)?"] + \
- options["--command-prompt"], int(options["--login-timeout"]))
- if result == 1:
- conn.sendline("yes")
- result = conn.log_expect(
- ["Enter passphrase for key '" + options["--identity-file"]+"':"] + \
- options["--command-prompt"], int(options["--login-timeout"]))
- if result == 0:
- if options.has_key("--password"):
- conn.sendline(options["--password"])
- conn.log_expect(options["--command-prompt"], int(options["--login-timeout"]))
- else:
- fail_usage("Failed: You have to enter passphrase (-p) for identity file")
+ conn = _login_ssh_with_identity_file(options)
else:
- conn = fspawn(options, options["--telnet-path"])
- conn.send("set binary\n")
- conn.send("open %s -%s\n"%(options["--ip"], options["--ipport"]))
-
- result = conn.log_expect(re_login, int(options["--login-timeout"]))
- conn.send_eol(options["--username"])
-
- ## automatically change end of line separator
- screen = conn.read_nonblocking(size=100, timeout=int(options["--shell-timeout"]))
- if re_login.search(screen) != None:
- options["eol"] = "\n"
- conn.send_eol(options["--username"])
- result = conn.log_expect(re_pass, int(options["--login-timeout"]))
- elif re_pass.search(screen) != None:
- conn.log_expect(re_pass, int(options["--shell-timeout"]))
-
- try:
- conn.send_eol(options["--password"])
- valid_password = conn.log_expect([re_login] + \
- options["--command-prompt"], int(options["--shell-timeout"]))
- if valid_password == 0:
- ## password is invalid or we have to change EOL separator
- options["eol"] = "\r"
- conn.send_eol("")
- screen = conn.read_nonblocking(size=100, timeout=int(options["--shell-timeout"]))
- ## after sending EOL the fence device can either show 'Login' or 'Password'
- if re_login.search(screen) != None:
- conn.send_eol("")
- conn.send_eol(options["--username"])
- conn.log_expect(re_pass, int(options["--login-timeout"]))
- conn.send_eol(options["--password"])
- conn.log_expect(options["--command-prompt"], int(options["--login-timeout"]))
- except KeyError:
- fail(EC_PASSWORD_MISSING)
+ conn = _login_telnet(options, re_login_string)
except pexpect.EOF:
fail(EC_LOGIN_DENIED)
except pexpect.TIMEOUT:
@@ -1221,3 +1111,141 @@ class SyslogLibHandler(logging.StreamHandler):
# syslos.syslog can not have 0x00 character inside or exception is thrown
syslog.syslog(syslog_level, msg.replace("\x00", "\n"))
return
+
+def _open_ssl_connection(options):
+ gnutls_opts = ""
+ ssl_opts = ""
+
+ if options.has_key("--notls"):
+ gnutls_opts = "--priority \"NORMAL:-VERS-TLS1.2:-VERS-TLS1.1:-VERS-TLS1.0:+VERS-SSL3.0\""
+
+ # --ssl is same as the --ssl-secure; it means we want to verify certificate in these cases
+ if options.has_key("--ssl-insecure"):
+ ssl_opts = "--insecure"
+
+ command = '%s %s %s --crlf -p %s %s' % \
+ (options["--gnutlscli-path"], gnutls_opts, ssl_opts, options["--ipport"], options["--ip"])
+ try:
+ conn = fspawn(options, command)
+ except pexpect.ExceptionPexpect, ex:
+ logging.error("%s\n", str(ex))
+ sys.exit(EC_GENERIC_ERROR)
+
+ return conn
+
+def _login_ssh_with_identity_file(options):
+ if options.has_key("--inet6-only"):
+ force_ipvx = "-6 "
+ elif options.has_key("--inet4-only"):
+ force_ipvx = "-4 "
+ else:
+ force_ipvx = ""
+
+ command = '%s %s %s@%s -i %s -p %s' % \
+ (options["--ssh-path"], force_ipvx, options["--username"], options["--ip"], \
+ options["--identity-file"], options["--ipport"])
+ if options.has_key("--ssh-options"):
+ command += ' ' + options["--ssh-options"]
+
+ conn = fspawn(options, command)
+
+ result = conn.log_expect(["Enter passphrase for key '" + options["--identity-file"] + "':", \
+ "Are you sure you want to continue connecting (yes/no)?"] + \
+ options["--command-prompt"], int(options["--login-timeout"]))
+ if result == 1:
+ conn.sendline("yes")
+ result = conn.log_expect(
+ ["Enter passphrase for key '" + options["--identity-file"]+"':"] + \
+ options["--command-prompt"], int(options["--login-timeout"]))
+ if result == 0:
+ if options.has_key("--password"):
+ conn.sendline(options["--password"])
+ conn.log_expect(options["--command-prompt"], int(options["--login-timeout"]))
+ else:
+ fail_usage("Failed: You have to enter passphrase (-p) for identity file")
+
+ return conn
+
+def _login_telnet(options, re_login_string):
+ re_login = re.compile(re_login_string, re.IGNORECASE)
+ re_pass = re.compile("(password)|(pass phrase)", re.IGNORECASE)
+
+ conn = fspawn(options, options["--telnet-path"])
+ conn.send("set binary\n")
+ conn.send("open %s -%s\n"%(options["--ip"], options["--ipport"]))
+
+ conn.log_expect(re_login, int(options["--login-timeout"]))
+ conn.send_eol(options["--username"])
+
+ ## automatically change end of line separator
+ screen = conn.read_nonblocking(size=100, timeout=int(options["--shell-timeout"]))
+ if re_login.search(screen) != None:
+ options["eol"] = "\n"
+ conn.send_eol(options["--username"])
+ conn.log_expect(re_pass, int(options["--login-timeout"]))
+ elif re_pass.search(screen) != None:
+ conn.log_expect(re_pass, int(options["--shell-timeout"]))
+
+ try:
+ conn.send_eol(options["--password"])
+ valid_password = conn.log_expect([re_login] + \
+ options["--command-prompt"], int(options["--shell-timeout"]))
+ if valid_password == 0:
+ ## password is invalid or we have to change EOL separator
+ options["eol"] = "\r"
+ conn.send_eol("")
+ screen = conn.read_nonblocking(size=100, timeout=int(options["--shell-timeout"]))
+ ## after sending EOL the fence device can either show 'Login' or 'Password'
+ if re_login.search(screen) != None:
+ conn.send_eol("")
+ conn.send_eol(options["--username"])
+ conn.log_expect(re_pass, int(options["--login-timeout"]))
+ conn.send_eol(options["--password"])
+ conn.log_expect(options["--command-prompt"], int(options["--login-timeout"]))
+ except KeyError:
+ fail(EC_PASSWORD_MISSING)
+
+ return conn
+
+def _login_ssh_with_password(options, re_login_string):
+ re_login = re.compile(re_login_string, re.IGNORECASE)
+ re_pass = re.compile("(password)|(pass phrase)", re.IGNORECASE)
+
+ if options.has_key("--inet6-only"):
+ force_ipvx = "-6 "
+ elif options.has_key("--inet4-only"):
+ force_ipvx = "-4 "
+ else:
+ force_ipvx = ""
+
+ command = '%s %s %s@%s -p %s -o PubkeyAuthentication=no' % \
+ (options["--ssh-path"], force_ipvx, options["--username"], options["--ip"], options["--ipport"])
+ if options.has_key("--ssh-options"):
+ command += ' ' + options["--ssh-options"]
+
+ conn = fspawn(options, command)
+
+ if options.has_key("telnet_over_ssh"):
+ # This is for stupid ssh servers (like ALOM) which behave more like telnet
+ # (ignore name and display login prompt)
+ result = conn.log_expect( \
+ [re_login, "Are you sure you want to continue connecting (yes/no)?"],
+ int(options["--login-timeout"]))
+ if result == 1:
+ conn.sendline("yes") # Host identity confirm
+ conn.log_expect(re_login, int(options["--login-timeout"]))
+
+ conn.sendline(options["--username"])
+ conn.log_expect(re_pass, int(options["--login-timeout"]))
+ else:
+ result = conn.log_expect( \
+ ["ssword:", "Are you sure you want to continue connecting (yes/no)?"],
+ int(options["--login-timeout"]))
+ if result == 1:
+ conn.sendline("yes")
+ conn.log_expect("ssword:", int(options["--login-timeout"]))
+
+ conn.sendline(options["--password"])
+ conn.log_expect(options["--command-prompt"], int(options["--login-timeout"]))
+
+ return conn
9 years, 6 months