From 64e3f3ef4d0abefd2836fe015c87173310b1e130 Mon Sep 17 00:00:00 2001 From: Jose Delarosa <jose.delarosa@dell.com> Date: Mon, 3 Dec 2018 10:11:15 -0600 Subject: [PATCH 1/8] Add new fence agent for Redfish - Agent works on all fence devices that implement the Redfish API specification - Agent programatically finds the Systems Resouce URI if it's not provided --- agents/redfish/fence_redfish.py | 151 +++++++++++++++++++++ tests/data/metadata/fence_redfish.xml | 181 ++++++++++++++++++++++++++ 2 files changed, 332 insertions(+) create mode 100644 agents/redfish/fence_redfish.py create mode 100644 tests/data/metadata/fence_redfish.xml diff --git a/agents/redfish/fence_redfish.py b/agents/redfish/fence_redfish.py new file mode 100644 index 00000000..df7cf8c2 --- /dev/null +++ b/agents/redfish/fence_redfish.py @@ -0,0 +1,151 @@ +#!@PYTHON@ -tt + +# Copyright (c) 2018 Dell Inc. or its subsidiaries. All Rights Reserved. + +# Fence agent for devices that support the Redfish API Specification. + +import sys +import re +import json +import requests +import atexit +sys.path.append("@FENCEAGENTSLIBDIR@") + +from requests.packages.urllib3.exceptions import InsecureRequestWarning +from fencing import * +from fencing import fail_usage + +def get_power_status(conn, options): + uri = options["--systems-uri"] + response = send_get_request(options, uri) + if response['ret'] is False: + fail_usage("Couldn't get power information") + data = response['data'] + if data[u'PowerState'].strip() == "On": + return "on" + else: + return "off" + +def set_power_status(conn, options): + action = { + 'on' : "On", + 'off': "ForceOff", + 'reboot': "GracefulRestart" + }[options["--action"]] + + payload = {'ResetType': action} + headers = {'content-type': 'application/json'} + + # Search for 'Actions' key and extract URI from it + uri = options["--systems-uri"] + response = send_get_request(options, uri) + if response['ret'] is False: + return {'ret': False} + data = response['data'] + uri = data["Actions"]["#ComputerSystem.Reset"]["target"] + + response = send_post_request(options, uri, payload, headers) + if response['ret'] is False: + fail_usage("Error sending power command") + return + +def send_get_request(options, uri): + full_uri = "https://" + options["--ip"] + uri + try: + resp = requests.get(full_uri, verify=False, + auth=(options["--username"], options["--password"])) + data = resp.json() + except: + return {'ret': False} + return {'ret': True, 'data': data} + +def send_post_request(options, uri, payload, headers): + full_uri = "https://" + options["--ip"] + uri + try: + requests.post(full_uri, data=json.dumps(payload), + headers=headers, verify=False, + auth=(options["--username"], options["--password"])) + except: + return {'ret': False} + return {'ret': True} + +def find_systems_resource(options): + uri = options["--redfish-uri"] + response = send_get_request(options, uri) + if response['ret'] is False: + return {'ret': False} + data = response['data'] + + if 'Systems' not in data: + # Systems resource not found" + return {'ret': False} + else: + uri = data["Systems"]["@odata.id"] + response = send_get_request(options, uri) + if response['ret'] is False: + return {'ret': False} + data = response['data'] + + # need to be able to handle more than one entry + for member in data[u'Members']: + system_uri = member[u'@odata.id'] + return {'ret': True, 'uri': system_uri} + +def define_new_opts(): + all_opt["redfish-uri"] = { + "getopt" : ":", + "longopt" : "redfish-uri", + "help" : "--redfish-uri=[uri] Base or starting Redifsh URI", + "required" : "0", + "default" : "/redfish/v1", + "shortdesc" : "Base or starting Redfish URI", + "order": 1 + } + all_opt["systems-uri"] = { + "getopt" : ":", + "longopt" : "systems-uri", + "help" : "--systems-uri=[uri] Redfish Systems resource URI", + "required" : "0", + "shortdesc" : "Redfish Systems resource URI, i.e. /redfish/v1/Systems/System.Embedded.1", + "order": 1 + } + +def main(): + atexit.register(atexit_handler) + device_opt = ["ipaddr", "login", "passwd", "redfish-uri", "systems-uri", "ssl"] + define_new_opts() + + opt = process_input(device_opt) + + all_opt["ipport"]["default"] = "443" + options = check_input(device_opt, opt) + + docs = {} + docs["shortdesc"] = "I/O Fencing agent for Redfish" + docs["longdesc"] = "fence_redfish is an I/O Fencing agent which can be used with \ +Out-of-Band controllers that support Redfish APIs. These controllers provide remote \ +access to control power on a server." + docs["vendorurl"] = "http://www.dmtf.org" + show_docs(options, docs) + + ## + ## Operate the fencing device + #### + + # Disable insecure-certificate-warning message + if "--ssl-insecure" in opt: + requests.packages.urllib3.disable_warnings(InsecureRequestWarning) + + if "--systems-uri" not in opt: + # Systems URI not provided, find it + sysresult = find_systems_resource(options) + if sysresult['ret'] is False: + sys.exit(1) + else: + options["--systems-uri"] = sysresult["uri"] + + result = fence_action(None, options, set_power_status, get_power_status, None) + sys.exit(result) + +if __name__ == "__main__": + main() diff --git a/tests/data/metadata/fence_redfish.xml b/tests/data/metadata/fence_redfish.xml new file mode 100644 index 00000000..43d447d0 --- /dev/null +++ b/tests/data/metadata/fence_redfish.xml @@ -0,0 +1,181 @@ +<?xml version="1.0" ?> +<resource-agent name="fence_redfish" shortdesc="I/O Fencing agent for Redfish" > +<longdesc>fence_redfish is an I/O Fencing agent which can be used with Out-of-Band controllers that support Redfish APIs. These controllers provide remote access to control power on a server.</longdesc> +<vendor-url>http://www.dmtf.org</vendor-url> +<parameters> + <parameter name="ipport" unique="0" required="0"> + <getopt mixed="-u, --ipport=[port]" /> + <content type="integer" default="443" /> + <shortdesc lang="en">TCP/UDP port to use for connection with device</shortdesc> + </parameter> + <parameter name="ssl_secure" unique="0" required="0"> + <getopt mixed="--ssl-secure" /> + <content type="boolean" /> + <shortdesc lang="en">SSL connection with verifying fence device's certificate</shortdesc> + </parameter> + <parameter name="systems-uri" unique="0" required="0" deprecated="1"> + <getopt mixed="--systems-uri=[uri]" /> + <content type="string" /> + <shortdesc lang="en">Redfish Systems resource URI, i.e. /redfish/v1/Systems/System.Embedded.1</shortdesc> + </parameter> + <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="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="0" deprecated="1"> + <getopt mixed="-a, --ip=[ip]" /> + <content type="string" /> + <shortdesc lang="en">IP Address or Hostname</shortdesc> + </parameter> + <parameter name="port" unique="0" required="0" deprecated="1"> + <getopt mixed="-n, --plug=[ip]" /> + <content type="string" /> + <shortdesc lang="en">IP address or hostname of fencing device (together with --port-as-ip)</shortdesc> + </parameter> + <parameter name="passwd_script" unique="0" required="0" deprecated="1"> + <getopt mixed="-S, --password-script=[script]" /> + <content type="string" /> + <shortdesc lang="en">Script to retrieve password</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="passwd" unique="0" required="0" deprecated="1"> + <getopt mixed="-p, --password=[password]" /> + <content type="string" /> + <shortdesc lang="en">Login password or passphrase</shortdesc> + </parameter> + <parameter name="ssl" unique="0" required="0"> + <getopt mixed="-z, --ssl" /> + <content type="boolean" /> + <shortdesc lang="en">SSL connection</shortdesc> + </parameter> + <parameter name="redfish-uri" unique="0" required="0" deprecated="1"> + <getopt mixed="--redfish-uri=[uri]" /> + <content type="string" default="/redfish/v1" /> + <shortdesc lang="en">Base or starting Redfish URI</shortdesc> + </parameter> + <parameter name="ssl_insecure" unique="0" required="0"> + <getopt mixed="--ssl-insecure" /> + <content type="boolean" /> + <shortdesc lang="en">SSL connection without verifying fence device's certificate</shortdesc> + </parameter> + <parameter name="login" unique="0" required="1" deprecated="1"> + <getopt mixed="-l, --username=[name]" /> + <content type="string" /> + <shortdesc lang="en">Login Name</shortdesc> + </parameter> + <parameter name="plug" unique="0" required="0" obsoletes="port"> + <getopt mixed="-n, --plug=[ip]" /> + <content type="string" /> + <shortdesc lang="en">IP address or hostname of fencing device (together with --port-as-ip)</shortdesc> + </parameter> + <parameter name="username" unique="0" required="1" obsoletes="login"> + <getopt mixed="-l, --username=[name]" /> + <content type="string" /> + <shortdesc lang="en">Login Name</shortdesc> + </parameter> + <parameter name="redfish_uri" unique="0" required="0" obsoletes="redfish-uri"> + <getopt mixed="--redfish-uri=[uri]" /> + <content type="string" default="/redfish/v1" /> + <shortdesc lang="en">Base or starting Redfish URI</shortdesc> + </parameter> + <parameter name="ip" unique="0" required="0" obsoletes="ipaddr"> + <getopt mixed="-a, --ip=[ip]" /> + <content type="string" /> + <shortdesc lang="en">IP Address or Hostname</shortdesc> + </parameter> + <parameter name="systems_uri" unique="0" required="0" obsoletes="systems-uri"> + <getopt mixed="--systems-uri=[uri]" /> + <content type="string" /> + <shortdesc lang="en">Redfish Systems resource URI, i.e. /redfish/v1/Systems/System.Embedded.1</shortdesc> + </parameter> + <parameter name="password" unique="0" required="0" obsoletes="passwd"> + <getopt mixed="-p, --password=[password]" /> + <content type="string" /> + <shortdesc lang="en">Login password or passphrase</shortdesc> + </parameter> + <parameter name="password_script" unique="0" required="0" obsoletes="passwd_script"> + <getopt mixed="-S, --password-script=[script]" /> + <content type="string" /> + <shortdesc lang="en">Script to retrieve password</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" deprecated="1"> + <getopt mixed="-D, --debug-file=[debugfile]" /> + <content type="string" /> + <shortdesc lang="en">Write debug information to given file</shortdesc> + </parameter> + <parameter name="debug_file" unique="0" required="0" obsoletes="debug"> + <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="power_wait" unique="0" required="0"> + <getopt mixed="--power-wait=[seconds]" /> + <content type="second" default="0" /> + <shortdesc lang="en">Wait X seconds after issuing ON/OFF</shortdesc> + </parameter> + <parameter name="login_timeout" unique="0" required="0"> + <getopt mixed="--login-timeout=[seconds]" /> + <content type="second" 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="second" default="20" /> + <shortdesc lang="en">Test X seconds for status change after ON/OFF</shortdesc> + </parameter> + <parameter name="delay" unique="0" required="0"> + <getopt mixed="--delay=[seconds]" /> + <content type="second" default="0" /> + <shortdesc lang="en">Wait X seconds before fencing is started</shortdesc> + </parameter> + <parameter name="shell_timeout" unique="0" required="0"> + <getopt mixed="--shell-timeout=[seconds]" /> + <content type="second" default="3" /> + <shortdesc lang="en">Wait X seconds for cmd prompt after issuing command</shortdesc> + </parameter> + <parameter name="port_as_ip" unique="0" required="0"> + <getopt mixed="--port-as-ip" /> + <content type="boolean" /> + <shortdesc lang="en">Make "port/plug" to be an alias to IP address</shortdesc> + </parameter> + <parameter name="retry_on" unique="0" required="0"> + <getopt mixed="--retry-on=[attempts]" /> + <content type="integer" 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="monitor" /> + <action name="metadata" /> + <action name="validate-all" /> +</actions> +</resource-agent> From 6921a34d64d098a7b1f32205e0be434438c36898 Mon Sep 17 00:00:00 2001 From: Jose Delarosa <jose.delarosa@dell.com> Date: Mon, 3 Dec 2018 10:46:52 -0600 Subject: [PATCH 2/8] Updated fence_redfish.xml with make xml-upload --- tests/data/metadata/fence_redfish.xml | 148 ++++++++++++++------------ 1 file changed, 79 insertions(+), 69 deletions(-) diff --git a/tests/data/metadata/fence_redfish.xml b/tests/data/metadata/fence_redfish.xml index 43d447d0..a39541e6 100644 --- a/tests/data/metadata/fence_redfish.xml +++ b/tests/data/metadata/fence_redfish.xml @@ -3,110 +3,115 @@ <longdesc>fence_redfish is an I/O Fencing agent which can be used with Out-of-Band controllers that support Redfish APIs. These controllers provide remote access to control power on a server.</longdesc> <vendor-url>http://www.dmtf.org</vendor-url> <parameters> - <parameter name="ipport" unique="0" required="0"> - <getopt mixed="-u, --ipport=[port]" /> - <content type="integer" default="443" /> - <shortdesc lang="en">TCP/UDP port to use for connection with device</shortdesc> - </parameter> - <parameter name="ssl_secure" unique="0" required="0"> - <getopt mixed="--ssl-secure" /> - <content type="boolean" /> - <shortdesc lang="en">SSL connection with verifying fence device's certificate</shortdesc> - </parameter> - <parameter name="systems-uri" unique="0" required="0" deprecated="1"> - <getopt mixed="--systems-uri=[uri]" /> - <content type="string" /> - <shortdesc lang="en">Redfish Systems resource URI, i.e. /redfish/v1/Systems/System.Embedded.1</shortdesc> - </parameter> <parameter name="action" unique="0" required="1"> <getopt mixed="-o, --action=[action]" /> <content type="string" default="reboot" /> - <shortdesc lang="en">Fencing Action</shortdesc> + <shortdesc lang="en">Fencing action</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="0" deprecated="1"> + <parameter name="ip" unique="0" required="0" obsoletes="ipaddr"> <getopt mixed="-a, --ip=[ip]" /> <content type="string" /> - <shortdesc lang="en">IP Address or Hostname</shortdesc> + <shortdesc lang="en">IP address or hostname of fencing device</shortdesc> </parameter> - <parameter name="port" unique="0" required="0" deprecated="1"> - <getopt mixed="-n, --plug=[ip]" /> + <parameter name="ipaddr" unique="0" required="0" deprecated="1"> + <getopt mixed="-a, --ip=[ip]" /> <content type="string" /> - <shortdesc lang="en">IP address or hostname of fencing device (together with --port-as-ip)</shortdesc> + <shortdesc lang="en">IP address or hostname of fencing device</shortdesc> </parameter> - <parameter name="passwd_script" unique="0" required="0" deprecated="1"> - <getopt mixed="-S, --password-script=[script]" /> - <content type="string" /> - <shortdesc lang="en">Script to retrieve password</shortdesc> + <parameter name="ipport" unique="0" required="0"> + <getopt mixed="-u, --ipport=[port]" /> + <content type="integer" default="443" /> + <shortdesc lang="en">TCP/UDP port to use for connection with device</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 name="login" unique="0" required="1" deprecated="1"> + <getopt mixed="-l, --username=[name]" /> + <content type="string" /> + <shortdesc lang="en">Login name</shortdesc> </parameter> <parameter name="passwd" unique="0" required="0" deprecated="1"> <getopt mixed="-p, --password=[password]" /> <content type="string" /> <shortdesc lang="en">Login password or passphrase</shortdesc> </parameter> - <parameter name="ssl" unique="0" required="0"> - <getopt mixed="-z, --ssl" /> - <content type="boolean" /> - <shortdesc lang="en">SSL connection</shortdesc> - </parameter> - <parameter name="redfish-uri" unique="0" required="0" deprecated="1"> - <getopt mixed="--redfish-uri=[uri]" /> - <content type="string" default="/redfish/v1" /> - <shortdesc lang="en">Base or starting Redfish URI</shortdesc> + <parameter name="passwd_script" unique="0" required="0" deprecated="1"> + <getopt mixed="-S, --password-script=[script]" /> + <content type="string" /> + <shortdesc lang="en">Script to run to retrieve password</shortdesc> </parameter> - <parameter name="ssl_insecure" unique="0" required="0"> - <getopt mixed="--ssl-insecure" /> - <content type="boolean" /> - <shortdesc lang="en">SSL connection without verifying fence device's certificate</shortdesc> + <parameter name="password" unique="0" required="0" obsoletes="passwd"> + <getopt mixed="-p, --password=[password]" /> + <content type="string" /> + <shortdesc lang="en">Login password or passphrase</shortdesc> </parameter> - <parameter name="login" unique="0" required="1" deprecated="1"> - <getopt mixed="-l, --username=[name]" /> + <parameter name="password_script" unique="0" required="0" obsoletes="passwd_script"> + <getopt mixed="-S, --password-script=[script]" /> <content type="string" /> - <shortdesc lang="en">Login Name</shortdesc> + <shortdesc lang="en">Script to run to retrieve password</shortdesc> </parameter> <parameter name="plug" unique="0" required="0" obsoletes="port"> <getopt mixed="-n, --plug=[ip]" /> <content type="string" /> <shortdesc lang="en">IP address or hostname of fencing device (together with --port-as-ip)</shortdesc> </parameter> - <parameter name="username" unique="0" required="1" obsoletes="login"> - <getopt mixed="-l, --username=[name]" /> + <parameter name="port" unique="0" required="0" deprecated="1"> + <getopt mixed="-n, --plug=[ip]" /> <content type="string" /> - <shortdesc lang="en">Login Name</shortdesc> + <shortdesc lang="en">IP address or hostname of fencing device (together with --port-as-ip)</shortdesc> + </parameter> + <parameter name="redfish-uri" unique="0" required="0" deprecated="1"> + <getopt mixed="--redfish-uri=[uri]" /> + <content type="string" default="/redfish/v1" /> + <shortdesc lang="en">Base or starting Redfish URI</shortdesc> </parameter> <parameter name="redfish_uri" unique="0" required="0" obsoletes="redfish-uri"> <getopt mixed="--redfish-uri=[uri]" /> <content type="string" default="/redfish/v1" /> <shortdesc lang="en">Base or starting Redfish URI</shortdesc> </parameter> - <parameter name="ip" unique="0" required="0" obsoletes="ipaddr"> - <getopt mixed="-a, --ip=[ip]" /> + <parameter name="ssl" unique="0" required="0"> + <getopt mixed="-z, --ssl" /> + <content type="boolean" /> + <shortdesc lang="en">Use SSL connection with verifying certificate</shortdesc> + </parameter> + <parameter name="ssl_insecure" unique="0" required="0"> + <getopt mixed="--ssl-insecure" /> + <content type="boolean" /> + <shortdesc lang="en">Use SSL connection without verifying certificate</shortdesc> + </parameter> + <parameter name="ssl_secure" unique="0" required="0"> + <getopt mixed="--ssl-secure" /> + <content type="boolean" /> + <shortdesc lang="en">Use SSL connection with verifying certificate</shortdesc> + </parameter> + <parameter name="systems-uri" unique="0" required="0" deprecated="1"> + <getopt mixed="--systems-uri=[uri]" /> <content type="string" /> - <shortdesc lang="en">IP Address or Hostname</shortdesc> + <shortdesc lang="en">Redfish Systems resource URI, i.e. /redfish/v1/Systems/System.Embedded.1</shortdesc> </parameter> <parameter name="systems_uri" unique="0" required="0" obsoletes="systems-uri"> <getopt mixed="--systems-uri=[uri]" /> <content type="string" /> <shortdesc lang="en">Redfish Systems resource URI, i.e. /redfish/v1/Systems/System.Embedded.1</shortdesc> </parameter> - <parameter name="password" unique="0" required="0" obsoletes="passwd"> - <getopt mixed="-p, --password=[password]" /> + <parameter name="username" unique="0" required="1" obsoletes="login"> + <getopt mixed="-l, --username=[name]" /> <content type="string" /> - <shortdesc lang="en">Login password or passphrase</shortdesc> + <shortdesc lang="en">Login name</shortdesc> </parameter> - <parameter name="password_script" unique="0" required="0" obsoletes="passwd_script"> - <getopt mixed="-S, --password-script=[script]" /> - <content type="string" /> - <shortdesc lang="en">Script to retrieve password</shortdesc> + <parameter name="quiet" unique="0" required="0"> + <getopt mixed="-q, --quiet" /> + <content type="boolean" /> + <shortdesc lang="en">Disable logging to stderr. Does not affect --verbose or --debug-file or logging to syslog.</shortdesc> </parameter> <parameter name="verbose" unique="0" required="0"> <getopt mixed="-v, --verbose" /> @@ -133,41 +138,45 @@ <content type="boolean" /> <shortdesc lang="en">Display help and exit</shortdesc> </parameter> - <parameter name="power_wait" unique="0" required="0"> - <getopt mixed="--power-wait=[seconds]" /> + <parameter name="delay" unique="0" required="0"> + <getopt mixed="--delay=[seconds]" /> <content type="second" default="0" /> - <shortdesc lang="en">Wait X seconds after issuing ON/OFF</shortdesc> + <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="second" default="5" /> <shortdesc lang="en">Wait X seconds for cmd prompt after login</shortdesc> </parameter> + <parameter name="port_as_ip" unique="0" required="0"> + <getopt mixed="--port-as-ip" /> + <content type="boolean" /> + <shortdesc lang="en">Make "port/plug" to be an alias to IP address</shortdesc> + </parameter> <parameter name="power_timeout" unique="0" required="0"> <getopt mixed="--power-timeout=[seconds]" /> <content type="second" default="20" /> <shortdesc lang="en">Test X seconds for status change after ON/OFF</shortdesc> </parameter> - <parameter name="delay" unique="0" required="0"> - <getopt mixed="--delay=[seconds]" /> + <parameter name="power_wait" unique="0" required="0"> + <getopt mixed="--power-wait=[seconds]" /> <content type="second" default="0" /> - <shortdesc lang="en">Wait X seconds before fencing is started</shortdesc> + <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="second" default="3" /> <shortdesc lang="en">Wait X seconds for cmd prompt after issuing command</shortdesc> </parameter> - <parameter name="port_as_ip" unique="0" required="0"> - <getopt mixed="--port-as-ip" /> - <content type="boolean" /> - <shortdesc lang="en">Make "port/plug" to be an alias to IP address</shortdesc> - </parameter> <parameter name="retry_on" unique="0" required="0"> <getopt mixed="--retry-on=[attempts]" /> <content type="integer" default="1" /> <shortdesc lang="en">Count of attempts to retry power on</shortdesc> </parameter> + <parameter name="gnutlscli_path" unique="0" required="0"> + <getopt mixed="--gnutlscli-path=[path]" /> + <shortdesc lang="en">Path to gnutls-cli binary</shortdesc> + </parameter> </parameters> <actions> <action name="on" automatic="0"/> @@ -176,6 +185,7 @@ <action name="status" /> <action name="monitor" /> <action name="metadata" /> + <action name="manpage" /> <action name="validate-all" /> </actions> </resource-agent> From 755627fadd711848ea256d72f5e75f36f83b4d31 Mon Sep 17 00:00:00 2001 From: Jose Delarosa <jose.delarosa@dell.com> Date: Mon, 3 Dec 2018 11:55:23 -0600 Subject: [PATCH 3/8] Added run_delay() --- agents/redfish/fence_redfish.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/agents/redfish/fence_redfish.py b/agents/redfish/fence_redfish.py index df7cf8c2..0e4a4f68 100644 --- a/agents/redfish/fence_redfish.py +++ b/agents/redfish/fence_redfish.py @@ -13,7 +13,7 @@ from requests.packages.urllib3.exceptions import InsecureRequestWarning from fencing import * -from fencing import fail_usage +from fencing import fail_usage, run_delay def get_power_status(conn, options): uri = options["--systems-uri"] @@ -127,6 +127,7 @@ def main(): access to control power on a server." docs["vendorurl"] = "http://www.dmtf.org" show_docs(options, docs) + run_delay(options) ## ## Operate the fencing device From 15fef4c47f391a3f03c714d86c9670ea209dec99 Mon Sep 17 00:00:00 2001 From: Jose Delarosa <jose.delarosa@dell.com> Date: Tue, 4 Dec 2018 10:56:58 -0600 Subject: [PATCH 4/8] Modify power status check - Only returns off if PowerState = Off - Otherwise returns on --- agents/redfish/fence_redfish.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/agents/redfish/fence_redfish.py b/agents/redfish/fence_redfish.py index 0e4a4f68..7998fb1c 100644 --- a/agents/redfish/fence_redfish.py +++ b/agents/redfish/fence_redfish.py @@ -21,10 +21,10 @@ def get_power_status(conn, options): if response['ret'] is False: fail_usage("Couldn't get power information") data = response['data'] - if data[u'PowerState'].strip() == "On": - return "on" - else: + if data[u'PowerState'].strip() == "Off": return "off" + else: + return "on" def set_power_status(conn, options): action = { From acf70f4672be65562841227ab0b4cacb87965f44 Mon Sep 17 00:00:00 2001 From: Jose Delarosa <jose.delarosa@dell.com> Date: Wed, 5 Dec 2018 10:39:32 -0600 Subject: [PATCH 5/8] Changed reboot type to ForceRestart --- agents/redfish/fence_redfish.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/agents/redfish/fence_redfish.py b/agents/redfish/fence_redfish.py index 7998fb1c..3fe2bfc0 100644 --- a/agents/redfish/fence_redfish.py +++ b/agents/redfish/fence_redfish.py @@ -30,7 +30,7 @@ def set_power_status(conn, options): action = { 'on' : "On", 'off': "ForceOff", - 'reboot': "GracefulRestart" + 'reboot': "ForceRestart" }[options["--action"]] payload = {'ResetType': action} From 56e3358d45050ac669c099c56873feefa1ecda38 Mon Sep 17 00:00:00 2001 From: Jose Delarosa <jose.delarosa@dell.com> Date: Wed, 5 Dec 2018 10:54:44 -0600 Subject: [PATCH 6/8] Replaced default port 443 with default ssl enabled option --- agents/redfish/fence_redfish.py | 2 +- tests/data/metadata/fence_redfish.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/agents/redfish/fence_redfish.py b/agents/redfish/fence_redfish.py index 3fe2bfc0..6a2dbb76 100644 --- a/agents/redfish/fence_redfish.py +++ b/agents/redfish/fence_redfish.py @@ -117,7 +117,7 @@ def main(): opt = process_input(device_opt) - all_opt["ipport"]["default"] = "443" + all_opt["ssl"]["default"] = "1" options = check_input(device_opt, opt) docs = {} diff --git a/tests/data/metadata/fence_redfish.xml b/tests/data/metadata/fence_redfish.xml index a39541e6..e1c18584 100644 --- a/tests/data/metadata/fence_redfish.xml +++ b/tests/data/metadata/fence_redfish.xml @@ -80,7 +80,7 @@ </parameter> <parameter name="ssl" unique="0" required="0"> <getopt mixed="-z, --ssl" /> - <content type="boolean" /> + <content type="boolean" default="1" /> <shortdesc lang="en">Use SSL connection with verifying certificate</shortdesc> </parameter> <parameter name="ssl_insecure" unique="0" required="0"> From 5c25a85b22a17d6bbc3dcb47c99b76e3a99a5857 Mon Sep 17 00:00:00 2001 From: Jose Delarosa <jose.delarosa@dell.com> Date: Wed, 5 Dec 2018 13:29:42 -0600 Subject: [PATCH 7/8] Renamed variable to avoid reusing variable name --- agents/redfish/fence_redfish.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/agents/redfish/fence_redfish.py b/agents/redfish/fence_redfish.py index 6a2dbb76..1ea25cd8 100644 --- a/agents/redfish/fence_redfish.py +++ b/agents/redfish/fence_redfish.py @@ -42,9 +42,9 @@ def set_power_status(conn, options): if response['ret'] is False: return {'ret': False} data = response['data'] - uri = data["Actions"]["#ComputerSystem.Reset"]["target"] + action_uri = data["Actions"]["#ComputerSystem.Reset"]["target"] - response = send_post_request(options, uri, payload, headers) + response = send_post_request(options, action_uri, payload, headers) if response['ret'] is False: fail_usage("Error sending power command") return From 7dce8b1e22d57fec0d34e91a99fab9d8a06f1303 Mon Sep 17 00:00:00 2001 From: Jose Delarosa <jose.delarosa@dell.com> Date: Thu, 6 Dec 2018 10:33:06 -0600 Subject: [PATCH 8/8] Removed unnecessary variable assignments to simplify code --- agents/redfish/fence_redfish.py | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/agents/redfish/fence_redfish.py b/agents/redfish/fence_redfish.py index 1ea25cd8..67ef67ab 100644 --- a/agents/redfish/fence_redfish.py +++ b/agents/redfish/fence_redfish.py @@ -16,8 +16,7 @@ from fencing import fail_usage, run_delay def get_power_status(conn, options): - uri = options["--systems-uri"] - response = send_get_request(options, uri) + response = send_get_request(options, options["--systems-uri"]) if response['ret'] is False: fail_usage("Couldn't get power information") data = response['data'] @@ -37,8 +36,7 @@ def set_power_status(conn, options): headers = {'content-type': 'application/json'} # Search for 'Actions' key and extract URI from it - uri = options["--systems-uri"] - response = send_get_request(options, uri) + response = send_get_request(options, options["--systems-uri"]) if response['ret'] is False: return {'ret': False} data = response['data'] @@ -70,8 +68,7 @@ def send_post_request(options, uri, payload, headers): return {'ret': True} def find_systems_resource(options): - uri = options["--redfish-uri"] - response = send_get_request(options, uri) + response = send_get_request(options, options["--redfish-uri"]) if response['ret'] is False: return {'ret': False} data = response['data'] @@ -80,8 +77,7 @@ def find_systems_resource(options): # Systems resource not found" return {'ret': False} else: - uri = data["Systems"]["@odata.id"] - response = send_get_request(options, uri) + response = send_get_request(options, data["Systems"]["@odata.id"]) if response['ret'] is False: return {'ret': False} data = response['data']