[PR #8434/961767e2 backport][stable-9] Redfish: Add options to check the availability of the service (#8457)

Redfish: Add options to check the availability of the service (#8434)

* Redfish: Add options to check the availability of the service

Signed-off-by: Mike Raineri <michael.raineri@dell.com>

* Updates based on review feedback

Signed-off-by: Mike Raineri <michael.raineri@dell.com>

* Updated comment to reflect changed behavior

Signed-off-by: Mike Raineri <michael.raineri@dell.com>

* Added changelog fragments

Signed-off-by: Mike Raineri <michael.raineri@dell.com>

* Update changelogs/fragments/8051-Redfish-Wait-For-Service.yml

Co-authored-by: Felix Fontein <felix@fontein.de>

* Update plugins/modules/redfish_command.py

Co-authored-by: Felix Fontein <felix@fontein.de>

* Update plugins/modules/redfish_command.py

Co-authored-by: Felix Fontein <felix@fontein.de>

* Update plugins/modules/redfish_command.py

Co-authored-by: Felix Fontein <felix@fontein.de>

* Update plugins/modules/redfish_command.py

Co-authored-by: Felix Fontein <felix@fontein.de>

---------

Signed-off-by: Mike Raineri <michael.raineri@dell.com>
Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit 961767e2dd)

Co-authored-by: Mike Raineri <mraineri@gmail.com>
This commit is contained in:
patchback[bot] 2024-06-03 07:15:58 +02:00 committed by GitHub
parent 9b8011d692
commit f214f206c3
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 102 additions and 9 deletions

View file

@ -11,6 +11,7 @@ import os
import random
import string
import gzip
import time
from io import BytesIO
from ansible.module_utils.urls import open_url
from ansible.module_utils.common.text.converters import to_native
@ -132,11 +133,13 @@ class RedfishUtils(object):
return resp
# The following functions are to send GET/POST/PATCH/DELETE requests
def get_request(self, uri, override_headers=None, allow_no_resp=False):
def get_request(self, uri, override_headers=None, allow_no_resp=False, timeout=None):
req_headers = dict(GET_HEADERS)
if override_headers:
req_headers.update(override_headers)
username, password, basic_auth = self._auth_params(req_headers)
if timeout is None:
timeout = self.timeout
try:
# Service root is an unauthenticated resource; remove credentials
# in case the caller will be using sessions later.
@ -146,7 +149,7 @@ class RedfishUtils(object):
url_username=username, url_password=password,
force_basic_auth=basic_auth, validate_certs=False,
follow_redirects='all',
use_proxy=True, timeout=self.timeout)
use_proxy=True, timeout=timeout)
headers = dict((k.lower(), v) for (k, v) in resp.info().items())
try:
if headers.get('content-encoding') == 'gzip' and LooseVersion(ansible_version) < LooseVersion('2.14'):
@ -624,6 +627,24 @@ class RedfishUtils(object):
allowable_values = default_values
return allowable_values
def check_service_availability(self):
"""
Checks if the service is accessible.
:return: dict containing the status of the service
"""
# Get the service root
# Override the timeout since the service root is expected to be readily
# available.
service_root = self.get_request(self.root_uri + self.service_root, timeout=10)
if service_root['ret'] is False:
# Failed, either due to a timeout or HTTP error; not available
return {'ret': True, 'available': False}
# Successfully accessed the service root; available
return {'ret': True, 'available': True}
def get_logs(self):
log_svcs_uri_list = []
list_of_logs = []
@ -1083,11 +1104,12 @@ class RedfishUtils(object):
return self.manage_power(command, self.systems_uri,
'#ComputerSystem.Reset')
def manage_manager_power(self, command):
def manage_manager_power(self, command, wait=False, wait_timeout=120):
return self.manage_power(command, self.manager_uri,
'#Manager.Reset')
'#Manager.Reset', wait, wait_timeout)
def manage_power(self, command, resource_uri, action_name):
def manage_power(self, command, resource_uri, action_name, wait=False,
wait_timeout=120):
key = "Actions"
reset_type_values = ['On', 'ForceOff', 'GracefulShutdown',
'GracefulRestart', 'ForceRestart', 'Nmi',
@ -1147,6 +1169,30 @@ class RedfishUtils(object):
response = self.post_request(self.root_uri + action_uri, payload)
if response['ret'] is False:
return response
# If requested to wait for the service to be available again, block
# until it's ready
if wait:
elapsed_time = 0
start_time = time.time()
# Start with a large enough sleep. Some services will process new
# requests while in the middle of shutting down, thus breaking out
# early.
time.sleep(30)
# Periodically check for the service's availability.
while elapsed_time <= wait_timeout:
status = self.check_service_availability()
if status['available']:
# It's available; we're done
break
time.sleep(5)
elapsed_time = time.time() - start_time
if elapsed_time > wait_timeout:
# Exhausted the wait timer; error
return {'ret': False, 'changed': True,
'msg': 'The service did not become available after %d seconds' % wait_timeout}
return {'ret': True, 'changed': True}
def manager_reset_to_defaults(self, command):