1
0
Fork 0
mirror of https://github.com/ansible-collections/community.general.git synced 2026-02-04 07:51:50 +00:00

Reformat everything.

This commit is contained in:
Felix Fontein 2025-11-01 12:08:41 +01:00
parent 3f2213791a
commit 340ff8586d
1008 changed files with 61301 additions and 58309 deletions

View file

@ -15,16 +15,15 @@ from ansible.module_utils.urls import open_url
from ansible.module_utils.common.text.converters import to_native
GET_HEADERS = {'accept': 'application/json'}
PUT_HEADERS = {'content-type': 'application/json', 'accept': 'application/json'}
POST_HEADERS = {'content-type': 'application/json', 'accept': 'application/json'}
DELETE_HEADERS = {'accept': 'application/json'}
GET_HEADERS = {"accept": "application/json"}
PUT_HEADERS = {"content-type": "application/json", "accept": "application/json"}
POST_HEADERS = {"content-type": "application/json", "accept": "application/json"}
DELETE_HEADERS = {"accept": "application/json"}
HEALTH_OK = 5
class OcapiUtils:
def __init__(self, creds, base_uri, proxy_slot_number, timeout, module):
self.root_uri = base_uri
self.proxy_slot_number = proxy_slot_number
@ -38,8 +37,8 @@ class OcapiUtils:
:return: tuple of username, password
"""
username = self.creds['user']
password = self.creds['pswd']
username = self.creds["user"]
password = self.creds["pswd"]
force_basic_auth = True
return username, password, force_basic_auth
@ -47,77 +46,89 @@ class OcapiUtils:
req_headers = dict(GET_HEADERS)
username, password, basic_auth = self._auth_params()
try:
resp = open_url(uri, method="GET", headers=req_headers,
url_username=username, url_password=password,
force_basic_auth=basic_auth, validate_certs=False,
follow_redirects='all',
use_proxy=True, timeout=self.timeout)
resp = open_url(
uri,
method="GET",
headers=req_headers,
url_username=username,
url_password=password,
force_basic_auth=basic_auth,
validate_certs=False,
follow_redirects="all",
use_proxy=True,
timeout=self.timeout,
)
data = json.loads(to_native(resp.read()))
headers = {k.lower(): v for (k, v) in resp.info().items()}
except HTTPError as e:
return {'ret': False,
'msg': f"HTTP Error {e.code} on GET request to '{uri}'",
'status': e.code}
return {"ret": False, "msg": f"HTTP Error {e.code} on GET request to '{uri}'", "status": e.code}
except URLError as e:
return {'ret': False, 'msg': f"URL Error on GET request to '{uri}': '{e.reason}'"}
return {"ret": False, "msg": f"URL Error on GET request to '{uri}': '{e.reason}'"}
# Almost all errors should be caught above, but just in case
except Exception as e:
return {'ret': False,
'msg': f"Failed GET request to '{uri}': '{e}'"}
return {'ret': True, 'data': data, 'headers': headers}
return {"ret": False, "msg": f"Failed GET request to '{uri}': '{e}'"}
return {"ret": True, "data": data, "headers": headers}
def delete_request(self, uri, etag=None):
req_headers = dict(DELETE_HEADERS)
if etag is not None:
req_headers['If-Match'] = etag
req_headers["If-Match"] = etag
username, password, basic_auth = self._auth_params()
try:
resp = open_url(uri, method="DELETE", headers=req_headers,
url_username=username, url_password=password,
force_basic_auth=basic_auth, validate_certs=False,
follow_redirects='all',
use_proxy=True, timeout=self.timeout)
resp = open_url(
uri,
method="DELETE",
headers=req_headers,
url_username=username,
url_password=password,
force_basic_auth=basic_auth,
validate_certs=False,
follow_redirects="all",
use_proxy=True,
timeout=self.timeout,
)
if resp.status != 204:
data = json.loads(to_native(resp.read()))
else:
data = ""
headers = {k.lower(): v for (k, v) in resp.info().items()}
except HTTPError as e:
return {'ret': False,
'msg': f"HTTP Error {e.code} on DELETE request to '{uri}'",
'status': e.code}
return {"ret": False, "msg": f"HTTP Error {e.code} on DELETE request to '{uri}'", "status": e.code}
except URLError as e:
return {'ret': False, 'msg': f"URL Error on DELETE request to '{uri}': '{e.reason}'"}
return {"ret": False, "msg": f"URL Error on DELETE request to '{uri}': '{e.reason}'"}
# Almost all errors should be caught above, but just in case
except Exception as e:
return {'ret': False,
'msg': f"Failed DELETE request to '{uri}': '{e}'"}
return {'ret': True, 'data': data, 'headers': headers}
return {"ret": False, "msg": f"Failed DELETE request to '{uri}': '{e}'"}
return {"ret": True, "data": data, "headers": headers}
def put_request(self, uri, payload, etag=None):
req_headers = dict(PUT_HEADERS)
if etag is not None:
req_headers['If-Match'] = etag
req_headers["If-Match"] = etag
username, password, basic_auth = self._auth_params()
try:
resp = open_url(uri, data=json.dumps(payload),
headers=req_headers, method="PUT",
url_username=username, url_password=password,
force_basic_auth=basic_auth, validate_certs=False,
follow_redirects='all',
use_proxy=True, timeout=self.timeout)
resp = open_url(
uri,
data=json.dumps(payload),
headers=req_headers,
method="PUT",
url_username=username,
url_password=password,
force_basic_auth=basic_auth,
validate_certs=False,
follow_redirects="all",
use_proxy=True,
timeout=self.timeout,
)
headers = {k.lower(): v for (k, v) in resp.info().items()}
except HTTPError as e:
return {'ret': False,
'msg': f"HTTP Error {e.code} on PUT request to '{uri}'",
'status': e.code}
return {"ret": False, "msg": f"HTTP Error {e.code} on PUT request to '{uri}'", "status": e.code}
except URLError as e:
return {'ret': False, 'msg': f"URL Error on PUT request to '{uri}': '{e.reason}'"}
return {"ret": False, "msg": f"URL Error on PUT request to '{uri}': '{e.reason}'"}
# Almost all errors should be caught above, but just in case
except Exception as e:
return {'ret': False,
'msg': f"Failed PUT request to '{uri}': '{e}'"}
return {'ret': True, 'headers': headers, 'resp': resp}
return {"ret": False, "msg": f"Failed PUT request to '{uri}': '{e}'"}
return {"ret": True, "headers": headers, "resp": resp}
def post_request(self, uri, payload, content_type="application/json", timeout=None):
req_headers = dict(POST_HEADERS)
@ -129,24 +140,28 @@ class OcapiUtils:
else:
request_data = payload
try:
resp = open_url(uri, data=request_data,
headers=req_headers, method="POST",
url_username=username, url_password=password,
force_basic_auth=basic_auth, validate_certs=False,
follow_redirects='all',
use_proxy=True, timeout=self.timeout if timeout is None else timeout)
resp = open_url(
uri,
data=request_data,
headers=req_headers,
method="POST",
url_username=username,
url_password=password,
force_basic_auth=basic_auth,
validate_certs=False,
follow_redirects="all",
use_proxy=True,
timeout=self.timeout if timeout is None else timeout,
)
headers = {k.lower(): v for (k, v) in resp.info().items()}
except HTTPError as e:
return {'ret': False,
'msg': f"HTTP Error {e.code} on POST request to '{uri}'",
'status': e.code}
return {"ret": False, "msg": f"HTTP Error {e.code} on POST request to '{uri}'", "status": e.code}
except URLError as e:
return {'ret': False, 'msg': f"URL Error on POST request to '{uri}': '{e.reason}'"}
return {"ret": False, "msg": f"URL Error on POST request to '{uri}': '{e.reason}'"}
# Almost all errors should be caught above, but just in case
except Exception as e:
return {'ret': False,
'msg': f"Failed POST request to '{uri}': '{e}'"}
return {'ret': True, 'headers': headers, 'resp': resp}
return {"ret": False, "msg": f"Failed POST request to '{uri}': '{e}'"}
return {"ret": True, "headers": headers, "resp": resp}
def get_uri_with_slot_number_query_param(self, uri):
"""Return the URI with proxy slot number added as a query param, if there is one.
@ -172,29 +187,25 @@ class OcapiUtils:
# Get the resource so that we have the Etag
response = self.get_request(resource_uri)
if 'etag' not in response['headers']:
return {'ret': False, 'msg': 'Etag not found in response.'}
etag = response['headers']['etag']
if response['ret'] is False:
if "etag" not in response["headers"]:
return {"ret": False, "msg": "Etag not found in response."}
etag = response["headers"]["etag"]
if response["ret"] is False:
return response
# Issue the PUT to do the reboot (unless we are in check mode)
if self.module.check_mode:
return {
'ret': True,
'changed': True,
'msg': 'Update not performed in check mode.'
}
payload = {'Reboot': True}
return {"ret": True, "changed": True, "msg": "Update not performed in check mode."}
payload = {"Reboot": True}
response = self.put_request(resource_uri, payload, etag)
if response['ret'] is False:
if response["ret"] is False:
return response
elif command.startswith("PowerMode"):
return self.manage_power_mode(command)
else:
return {'ret': False, 'msg': f"Invalid command: {command}"}
return {"ret": False, "msg": f"Invalid command: {command}"}
return {'ret': True}
return {"ret": True}
def manage_chassis_indicator_led(self, command):
"""Process a command to manage the chassis indicator LED.
@ -214,91 +225,73 @@ class OcapiUtils:
resource_uri = self.root_uri
resource_uri = self.get_uri_with_slot_number_query_param(resource_uri)
payloads = {
'IndicatorLedOn': {
'ID': 2
},
'IndicatorLedOff': {
'ID': 4
}
}
payloads = {"IndicatorLedOn": {"ID": 2}, "IndicatorLedOff": {"ID": 4}}
response = self.get_request(resource_uri)
if 'etag' not in response['headers']:
return {'ret': False, 'msg': 'Etag not found in response.'}
etag = response['headers']['etag']
if response['ret'] is False:
if "etag" not in response["headers"]:
return {"ret": False, "msg": "Etag not found in response."}
etag = response["headers"]["etag"]
if response["ret"] is False:
return response
data = response['data']
data = response["data"]
if key not in data:
return {'ret': False, 'msg': f"Key {key} not found"}
if 'ID' not in data[key]:
return {'ret': False, 'msg': 'IndicatorLED for resource has no ID.'}
return {"ret": False, "msg": f"Key {key} not found"}
if "ID" not in data[key]:
return {"ret": False, "msg": "IndicatorLED for resource has no ID."}
if command in payloads.keys():
# See if the LED is already set as requested.
current_led_status = data[key]['ID']
if current_led_status == payloads[command]['ID']:
return {'ret': True, 'changed': False}
current_led_status = data[key]["ID"]
if current_led_status == payloads[command]["ID"]:
return {"ret": True, "changed": False}
# Set the LED (unless we are in check mode)
if self.module.check_mode:
return {
'ret': True,
'changed': True,
'msg': 'Update not performed in check mode.'
}
payload = {'IndicatorLED': payloads[command]}
return {"ret": True, "changed": True, "msg": "Update not performed in check mode."}
payload = {"IndicatorLED": payloads[command]}
response = self.put_request(resource_uri, payload, etag)
if response['ret'] is False:
if response["ret"] is False:
return response
else:
return {'ret': False, 'msg': 'Invalid command'}
return {"ret": False, "msg": "Invalid command"}
return {'ret': True}
return {"ret": True}
def manage_power_mode(self, command):
key = "PowerState"
resource_uri = self.get_uri_with_slot_number_query_param(self.root_uri)
payloads = {
"PowerModeNormal": 2,
"PowerModeLow": 4
}
payloads = {"PowerModeNormal": 2, "PowerModeLow": 4}
response = self.get_request(resource_uri)
if 'etag' not in response['headers']:
return {'ret': False, 'msg': 'Etag not found in response.'}
etag = response['headers']['etag']
if response['ret'] is False:
if "etag" not in response["headers"]:
return {"ret": False, "msg": "Etag not found in response."}
etag = response["headers"]["etag"]
if response["ret"] is False:
return response
data = response['data']
data = response["data"]
if key not in data:
return {'ret': False, 'msg': f"Key {key} not found"}
if 'ID' not in data[key]:
return {'ret': False, 'msg': 'PowerState for resource has no ID.'}
return {"ret": False, "msg": f"Key {key} not found"}
if "ID" not in data[key]:
return {"ret": False, "msg": "PowerState for resource has no ID."}
if command in payloads.keys():
# See if the PowerState is already set as requested.
current_power_state = data[key]['ID']
current_power_state = data[key]["ID"]
if current_power_state == payloads[command]:
return {'ret': True, 'changed': False}
return {"ret": True, "changed": False}
# Set the Power State (unless we are in check mode)
if self.module.check_mode:
return {
'ret': True,
'changed': True,
'msg': 'Update not performed in check mode.'
}
payload = {'PowerState': {"ID": payloads[command]}}
return {"ret": True, "changed": True, "msg": "Update not performed in check mode."}
payload = {"PowerState": {"ID": payloads[command]}}
response = self.put_request(resource_uri, payload, etag)
if response['ret'] is False:
if response["ret"] is False:
return response
else:
return {'ret': False, 'msg': f"Invalid command: {command}"}
return {"ret": False, "msg": f"Invalid command: {command}"}
return {'ret': True}
return {"ret": True}
def prepare_multipart_firmware_upload(self, filename):
"""Prepare a multipart/form-data body for OCAPI firmware upload.
@ -315,13 +308,12 @@ class OcapiUtils:
boundary = str(uuid.uuid4()) # Generate a random boundary
body = f"--{boundary}\r\n"
body += f'Content-Disposition: form-data; name="FirmwareFile"; filename="{to_native(os.path.basename(filename))}"\r\n'
body += 'Content-Type: application/octet-stream\r\n\r\n'
body_bytes = bytearray(body, 'utf-8')
with open(filename, 'rb') as f:
body += "Content-Type: application/octet-stream\r\n\r\n"
body_bytes = bytearray(body, "utf-8")
with open(filename, "rb") as f:
body_bytes += f.read()
body_bytes += bytearray(f"\r\n--{boundary}--", 'utf-8')
return (f"multipart/form-data; boundary={boundary}",
body_bytes)
body_bytes += bytearray(f"\r\n--{boundary}--", "utf-8")
return (f"multipart/form-data; boundary={boundary}", body_bytes)
def upload_firmware_image(self, update_image_path):
"""Perform Firmware Upload to the OCAPI storage device.
@ -329,22 +321,18 @@ class OcapiUtils:
:param str update_image_path: The path/filename of the firmware image, on the local filesystem.
"""
if not (os.path.exists(update_image_path) and os.path.isfile(update_image_path)):
return {'ret': False, 'msg': 'File does not exist.'}
return {"ret": False, "msg": "File does not exist."}
url = f"{self.root_uri}OperatingSystem"
url = self.get_uri_with_slot_number_query_param(url)
content_type, b_form_data = self.prepare_multipart_firmware_upload(update_image_path)
# Post the firmware (unless we are in check mode)
if self.module.check_mode:
return {
'ret': True,
'changed': True,
'msg': 'Update not performed in check mode.'
}
return {"ret": True, "changed": True, "msg": "Update not performed in check mode."}
result = self.post_request(url, b_form_data, content_type=content_type, timeout=300)
if result['ret'] is False:
if result["ret"] is False:
return result
return {'ret': True}
return {"ret": True}
def update_firmware_image(self):
"""Perform a Firmware Update on the OCAPI storage device."""
@ -352,25 +340,21 @@ class OcapiUtils:
resource_uri = self.get_uri_with_slot_number_query_param(resource_uri)
# We have to do a GET to obtain the Etag. It's required on the PUT.
response = self.get_request(resource_uri)
if response['ret'] is False:
if response["ret"] is False:
return response
if 'etag' not in response['headers']:
return {'ret': False, 'msg': 'Etag not found in response.'}
etag = response['headers']['etag']
if "etag" not in response["headers"]:
return {"ret": False, "msg": "Etag not found in response."}
etag = response["headers"]["etag"]
# Issue the PUT (unless we are in check mode)
if self.module.check_mode:
return {
'ret': True,
'changed': True,
'msg': 'Update not performed in check mode.'
}
payload = {'FirmwareUpdate': True}
return {"ret": True, "changed": True, "msg": "Update not performed in check mode."}
payload = {"FirmwareUpdate": True}
response = self.put_request(resource_uri, payload, etag)
if response['ret'] is False:
if response["ret"] is False:
return response
return {'ret': True, 'jobUri': response["headers"]["location"]}
return {"ret": True, "jobUri": response["headers"]["location"]}
def activate_firmware_image(self):
"""Perform a Firmware Activate on the OCAPI storage device."""
@ -378,25 +362,21 @@ class OcapiUtils:
resource_uri = self.get_uri_with_slot_number_query_param(resource_uri)
# We have to do a GET to obtain the Etag. It's required on the PUT.
response = self.get_request(resource_uri)
if 'etag' not in response['headers']:
return {'ret': False, 'msg': 'Etag not found in response.'}
etag = response['headers']['etag']
if response['ret'] is False:
if "etag" not in response["headers"]:
return {"ret": False, "msg": "Etag not found in response."}
etag = response["headers"]["etag"]
if response["ret"] is False:
return response
# Issue the PUT (unless we are in check mode)
if self.module.check_mode:
return {
'ret': True,
'changed': True,
'msg': 'Update not performed in check mode.'
}
payload = {'FirmwareActivate': True}
return {"ret": True, "changed": True, "msg": "Update not performed in check mode."}
payload = {"FirmwareActivate": True}
response = self.put_request(resource_uri, payload, etag)
if response['ret'] is False:
if response["ret"] is False:
return response
return {'ret': True, 'jobUri': response["headers"]["location"]}
return {"ret": True, "jobUri": response["headers"]["location"]}
def get_job_status(self, job_uri):
"""Get the status of a job.
@ -405,8 +385,8 @@ class OcapiUtils:
"""
job_uri = self.get_uri_with_slot_number_query_param(job_uri)
response = self.get_request(job_uri)
if response['ret'] is False:
if response.get('status') == 404:
if response["ret"] is False:
if response.get("status") == 404:
# Job not found -- assume 0%
return {
"ret": True,
@ -416,7 +396,7 @@ class OcapiUtils:
"operationHealth": None,
"operationHealthId": None,
"details": "Job does not exist.",
"jobExists": False
"jobExists": False,
}
else:
return response
@ -432,7 +412,7 @@ class OcapiUtils:
"operationHealth": health_list[0]["Name"] if len(health_list) > 0 else None,
"operationHealthId": health_list[0]["ID"] if len(health_list) > 0 else None,
"details": details,
"jobExists": True
"jobExists": True,
}
return return_value
@ -442,50 +422,28 @@ class OcapiUtils:
# We have to do a GET to obtain the Etag. It's required on the DELETE.
response = self.get_request(job_uri)
if response['ret'] is True:
if 'etag' not in response['headers']:
return {'ret': False, 'msg': 'Etag not found in response.'}
if response["ret"] is True:
if "etag" not in response["headers"]:
return {"ret": False, "msg": "Etag not found in response."}
else:
etag = response['headers']['etag']
etag = response["headers"]["etag"]
if response['data']['PercentComplete'] != 100:
return {
'ret': False,
'changed': False,
'msg': 'Cannot delete job because it is in progress.'
}
if response["data"]["PercentComplete"] != 100:
return {"ret": False, "changed": False, "msg": "Cannot delete job because it is in progress."}
if response['ret'] is False:
if response['status'] == 404:
return {
'ret': True,
'changed': False,
'msg': 'Job already deleted.'
}
if response["ret"] is False:
if response["status"] == 404:
return {"ret": True, "changed": False, "msg": "Job already deleted."}
return response
if self.module.check_mode:
return {
'ret': True,
'changed': True,
'msg': 'Update not performed in check mode.'
}
return {"ret": True, "changed": True, "msg": "Update not performed in check mode."}
# Do the DELETE (unless we are in check mode)
response = self.delete_request(job_uri, etag)
if response['ret'] is False:
if response['status'] == 404:
return {
'ret': True,
'changed': False
}
elif response['status'] == 409:
return {
'ret': False,
'changed': False,
'msg': 'Cannot delete job because it is in progress.'
}
if response["ret"] is False:
if response["status"] == 404:
return {"ret": True, "changed": False}
elif response["status"] == 409:
return {"ret": False, "changed": False, "msg": "Cannot delete job because it is in progress."}
return response
return {
'ret': True,
'changed': True
}
return {"ret": True, "changed": True}