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 @@ -1,152 +1,152 @@ #!@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, run_delay 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() == "Off": return "off" else: return "on" def set_power_status(conn, options): action = { 'on' : "On", 'off': "ForceOff", 'reboot': "ForceRestart" }[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" + all_opt["ssl"]["default"] = "1" 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) run_delay(options) ## ## 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 index a39541e6..e1c18584 100644 --- a/tests/data/metadata/fence_redfish.xml +++ b/tests/data/metadata/fence_redfish.xml @@ -1,191 +1,191 @@ 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. http://www.dmtf.org Fencing action Forces agent to use IPv4 addresses only Forces agent to use IPv6 addresses only IP address or hostname of fencing device IP address or hostname of fencing device TCP/UDP port to use for connection with device Login name Login password or passphrase Script to run to retrieve password Login password or passphrase Script to run to retrieve password IP address or hostname of fencing device (together with --port-as-ip) IP address or hostname of fencing device (together with --port-as-ip) Base or starting Redfish URI Base or starting Redfish URI - + Use SSL connection with verifying certificate Use SSL connection without verifying certificate Use SSL connection with verifying certificate Redfish Systems resource URI, i.e. /redfish/v1/Systems/System.Embedded.1 Redfish Systems resource URI, i.e. /redfish/v1/Systems/System.Embedded.1 Login name Disable logging to stderr. Does not affect --verbose or --debug-file or logging to syslog. Verbose mode Write debug information to given file Write debug information to given file Display version information and exit Display help and exit Wait X seconds before fencing is started Wait X seconds for cmd prompt after login Make "port/plug" to be an alias to IP address Test X seconds for status change after ON/OFF Wait X seconds after issuing ON/OFF Wait X seconds for cmd prompt after issuing command Count of attempts to retry power on Path to gnutls-cli binary