Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[idrac_secure_boot]: Attributes, Reset Keys and Export secure boot certificates #727

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
66771e4
Started export
ABHISHEK-SINHA10 Sep 2, 2024
64f7b34
Updated rst
ABHISHEK-SINHA10 Sep 2, 2024
ccf9b4d
Added doc and example
ABHISHEK-SINHA10 Sep 3, 2024
36798a0
Merge branch 'collections' into feature/idrac_secure_boot_export_oper…
ABHISHEK-SINHA10 Sep 3, 2024
ce5e1c8
sanity fix
ABHISHEK-SINHA10 Sep 3, 2024
f74215e
Updated documentation for attributes and reset operations
singh-lovepreet1 Sep 4, 2024
c68415e
Adding code
ABHISHEK-SINHA10 Sep 4, 2024
312ead8
Adding UT
ABHISHEK-SINHA10 Sep 4, 2024
5f14e56
Adding UT
ABHISHEK-SINHA10 Sep 4, 2024
2a7ed27
Fixing sonar
ABHISHEK-SINHA10 Sep 5, 2024
ab4c33c
Fixing sanity
ABHISHEK-SINHA10 Sep 5, 2024
1b5ea0e
Fixing sonar
ABHISHEK-SINHA10 Sep 5, 2024
ea74ce3
Adding attributes code
singh-lovepreet1 Sep 9, 2024
523b761
resolved sonar issues
singh-lovepreet1 Sep 9, 2024
a61a656
Message updates
singh-lovepreet1 Sep 9, 2024
5788c37
Added reset certificates operation
singh-lovepreet1 Sep 12, 2024
6aff5d7
Fixed Sonar issues
singh-lovepreet1 Sep 12, 2024
3ed7991
Merge branch 'collections' into feature/idrac_secure_boot_export_oper…
singh-lovepreet1 Sep 13, 2024
ea39f18
Minor Changes
singh-lovepreet1 Sep 14, 2024
87126fd
Added a scenario
singh-lovepreet1 Sep 16, 2024
b19507e
Updated IDRACAttribute feature
singh-lovepreet1 Sep 17, 2024
3cdc9ab
Fixed JIT-313693 and JIT-313801
singh-lovepreet1 Sep 19, 2024
62e016c
Fixed Sonar issues
singh-lovepreet1 Sep 19, 2024
5c8a2b2
Updated the documentation
singh-lovepreet1 Sep 20, 2024
d29258a
Merge branch 'collections' into feature/idrac_secure_boot_export_oper…
singh-lovepreet1 Sep 20, 2024
d6ec9de
Merge branch 'collections' into feature/idrac_secure_boot_export_oper…
rajshekarp87 Sep 20, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
160 changes: 151 additions & 9 deletions docs/modules/idrac_secure_boot.rst
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
.. _idrac_secure_boot_module:


idrac_secure_boot -- Import secure boot certificate.
====================================================
idrac_secure_boot -- Configure attributes, import, or export secure boot certificate, and reset keys.
=====================================================================================================

.. contents::
:local:
Expand All @@ -12,7 +12,17 @@ idrac_secure_boot -- Import secure boot certificate.
Synopsis
--------

This module allows to import the secure boot certificate.
This module allows you to perform the following operations.\`

Import or Export Secure Boot certificate.

Enable or disable Secure Boot mode.

Configure Platform Key (PK) and Key Exchange Key (KEK) policies

Configure Allow Database (DB) and Disallow Database (DBX) certificates.

Reset UEFI Secure Boot keys.



Expand All @@ -27,6 +37,62 @@ The below requirements are needed on the host that executes this module.
Parameters
----------

boot_mode (optional, str, None)
Boot mode of the iDRAC.

\ :literal:`Uefi`\ enables the secure boot in UEFI mode.

\ :literal:`Bios`\ enables the secure boot in BIOS mode.


secure_boot (optional, str, None)
UEFI Secure Boot.

The \ :emphasis:`secure\_boot`\ can be \ :literal:`Enabled`\ only if \ :emphasis:`boot\_mode`\ is \ :literal:`UEFI`\ and \ :emphasis:`force\_int\_10`\ is \ :literal:`Disabled`\ .

\ :literal:`Disabled`\ disables the secure boot mode.

\ :literal:`Enabled`\ enables the secure boot mode.


secure_boot_mode (optional, str, None)
The UEFI Secure Boot mode configures how to use the Secure Boot Policy.

\ :literal:`AuditMode`\ sets the Secure Boot mode to an Audit mode when Platform Key is not installed on the system. The BIOS does not authenticate updates to the policy objects and transition between modes. BIOS performs a signature verification on pre-boot images and logs the results in the Image Execution Information table, where it processes the images whether the status of verification is pass or fail.

\ :literal:`DeployedMode`\ sets the Secure Boot mode to a Deployed mode when Platform Key is installed on the system, and then BIOS performs a signature verification to update the policy objects.

\ :literal:`UserMode`\ sets the Secure Boot mode to a User mode when Platform Key is installed on the system, and then BIOS performs signature verification to update policy objects.


secure_boot_policy (optional, str, None)
The following are the types of Secure Boot policy.

\ :literal:`Custom`\ inherits the standard certificates and image digests that are loaded in the system by default. You can modify the certificates and image digests.

\ :literal:`Standard`\ indicates that the system has default certificates, image digests, or hash loaded from the factory.

When the Secure Boot Policy is set to Custom, you can perform following operations such as viewing, exporting, importing, deleting, deleting all, and resetting policies.


force_int_10 (optional, str, None)
Determines whether the system BIOS loads the legacy video (INT 10h) option ROM from the video controller.

This parameter is supported only in UEFI boot mode. If UEFI Secure Boot mode is enabled, you cannot enable this parameter.

\ :literal:`Disabled`\ if the operating system supports UEFI video output standards.

\ :literal:`Enabled`\ if the operating system does not support UEFI video output standards.


export_certificates (optional, bool, None)
Export all the available certificates in the specified directory for the given keys.

\ :emphasis:`export\_cetificates`\ is mutually exclusive with \ :emphasis:`import`\ .

\ :emphasis:`export\_cetificates`\ is \ :literal:`true`\ either of \ :emphasis:`platform\_key`\ or i(key\_exchange\_key) or \ :emphasis:`database`\ - or \ :emphasis:`disallow\_database`\ is required.


import_certificates (optional, bool, None)
Import all the specified key certificates.

Expand All @@ -36,17 +102,43 @@ Parameters
platform_key (optional, path, None)
The absolute path of the Platform key certificate file for UEFI secure boot.

Directory path with write permission when \ :emphasis:`export\_certificates`\ is \ :literal:`true`\ .


KEK (optional, list, None)
A list of absolute paths of the Key Exchange Key (KEK) certificate file for UEFI secure boot.

Directory path with write permission when \ :emphasis:`export\_certificates`\ is \ :literal:`true`\ .


database (optional, list, None)
A list of absolute paths of the Database certificate file for UEFI secure boot.
A list of absolute paths of the Allow Database(DB) certificate file for UEFI secure boot.

Directory path with write permission when \ :emphasis:`export\_certificates`\ is \ :literal:`true`\ .


disallow_database (optional, list, None)
A list of absolute paths of the Disallow Database certificate file for UEFI secure boot.
A list of absolute paths of the Disallow Database(DBX) certificate file for UEFI secure boot.

Directory path with write permission when \ :emphasis:`export\_certificates`\ is \ :literal:`true`\ .


reset_keys (optional, str, None)
Resets the UEFI Secure Boot keys.

\ :literal:`DeleteAllKeys`\ deletes the content of all UEFI Secure Boot key databases (PK, KEK, DB, and DBX). This choice configures the system in Setup Mode.

\ :literal:`DeletePK`\ deletes the content of the PK UEFI Secure Boot database. This choice configures the system in Setup Mode.

\ :literal:`ResetAllKeysToDefault`\ resets the content of all UEFI Secure Boot key databases (PK, KEK, DB, and DBX) to their default values.

\ :literal:`ResetDB`\ resets the content of the DB UEFI Secure Boot database to its default values.

\ :literal:`ResetDBX`\ resets the content of the DBX UEFI Secure Boot database to its default values.

\ :literal:`ResetKEK`\ resets the content of the KEK UEFI Secure Boot database to its default values.

\ :literal:`ResetPK`\ resets the content of the PK UEFI Secure Boot database to its default values.


restart (optional, bool, False)
Expand All @@ -58,6 +150,8 @@ Parameters

\ :emphasis:`restart`\ is applicable when \ :emphasis:`import\_certificates`\ is \ :literal:`true`\ .

\ :emphasis:`restart`\ will be ignored only when \ :emphasis:`export\_certificates`\ is \ :literal:`true`\ .


restart_type (optional, str, GracefulRestart)
Restart type of the server.
Expand Down Expand Up @@ -134,9 +228,13 @@ Notes
-----

.. note::
- This module will always report changes found to be applied when run in \ :literal:`check mode`\ .
- This module does not support idempotency when \ :emphasis:`import\_certificates`\ is provided.
- This module will always report changes found to be applied for \ :emphasis:`import\_certificates`\ when run in \ :literal:`check mode`\ .
- This module does not support idempotency when \ :emphasis:`reset\_type`\ or \ :emphasis:`export\_certificates`\ or \ :emphasis:`import\_certificates`\ is provided.
- To configure the secure boot settings, the idrac\_secure\_boot module performs the following order of operations set attributes, export certificate, reset keys, import certificate, and restart iDRAC.
- \ :emphasis:`export\_certificate`\ will export all the certificates of the key defined in the playbook.
- This module considers values of \ :emphasis:`restart`\ and \ :emphasis:`job\_wait`\ only for the last operation in the sequence.
- This module supports IPv4 and IPv6 addresses.
- Only \ :emphasis:`reset\_keys`\ is supported on iDRAC8.



Expand All @@ -148,7 +246,50 @@ Examples


---
- name: Import multiple SecureBoot certificate without applying to iDRAC.
- name: Enable Secure Boot.
dellemc.openmanage.idrac_secure_boot:
idrac_ip: "192.168.1.2"
idrac_user: "user"
idrac_password: "password"
ca_path: "/path/to/ca_cert.pem"
secure_boot: "Enabled"

- name: Set Secure Boot mode, Secure Boot policy, and restart iDRAC.
dellemc.openmanage.idrac_secure_boot:
idrac_ip: "192.168.1.2"
idrac_user: "user"
idrac_password: "password"
ca_path: "/path/to/ca_cert.pem"
secure_boot: "Enabled"
secure_boot_mode: "UserMode"
secure_boot_policy: "Custom"
restart: true
restart_type: "GracefulRestart"

- name: Reset Secure Boot certificates.
dellemc.openmanage.idrac_secure_boot:
idrac_ip: "192.168.1.2"
idrac_user: "user"
idrac_password: "password"
ca_path: "/path/to/ca_cert.pem"
reset_keys: "ResetAllKeysToDefault"

- name: Export multiple Secure Boot certificate.
dellemc.openmanage.idrac_secure_boot:
idrac_ip: "192.168.1.2"
idrac_user: "user"
idrac_password: "password"
ca_path: "/path/to/ca_cert.pem"
export_certificates: true
platform_key: /user/name/export_cert/pk
KEK:
- /user/name/export_cert/kek
database:
- /user/name/export_cert/db
disallow_database:
- /user/name/export_cert/dbx

- name: Import multiple Secure Boot certificate without applying to iDRAC.
dellemc.openmanage.idrac_secure_boot:
idrac_ip: "192.168.1.2"
idrac_user: "user"
Expand All @@ -166,7 +307,7 @@ Examples
- /user/name/certificates/dbx1.pem
- /user/name/certificates/dbx2.pem

- name: Import a SecureBoot certificate and restart the server to apply it.
- name: Import a Secure Boot certificate and restart the server to apply it.
dellemc.openmanage.idrac_secure_boot:
idrac_ip: "192.168.1.2"
idrac_user: "user"
Expand Down Expand Up @@ -204,4 +345,5 @@ Authors
~~~~~~~

- Abhishek Sinha(@ABHISHEK-SINHA10)
- Lovepreet Singh (@singh-lovepreet1)

51 changes: 49 additions & 2 deletions playbooks/idrac/idrac_secure_boot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,54 @@
gather_facts: false

tasks:
- name: Import multiple SecureBoot certificate without applying to iDRAC.
- name: Enable Secure Boot.
dellemc.openmanage.idrac_secure_boot:
idrac_ip: "192.168.1.2"
idrac_user: "user"
idrac_password: "password"
ca_path: "/path/to/ca_cert.pem"
secure_boot: "Enabled"
delegate_to: localhost

- name: Set Secure Boot mode and Secure Boot policy and restart iDRAC.
dellemc.openmanage.idrac_secure_boot:
idrac_ip: "192.168.1.2"
idrac_user: "user"
idrac_password: "password"
ca_path: "/path/to/ca_cert.pem"
secure_boot: "Enabled"
secure_boot_mode: "UserMode"
secure_boot_policy: "Custom"
restart: true
restart_type: "GracefulRestart"
delegate_to: localhost

- name: Reset Secure Boot certificates.
dellemc.openmanage.idrac_secure_boot:
idrac_ip: "192.168.1.2"
idrac_user: "user"
idrac_password: "password"
ca_path: "/path/to/ca_cert.pem"
reset_keys: "ResetAllKeysToDefault"
delegate_to: localhost

- name: Export multiple Secure Boot certificate.
dellemc.openmanage.idrac_secure_boot:
idrac_ip: "192.168.1.2"
idrac_user: "user"
idrac_password: "password"
ca_path: "/path/to/ca_cert.pem"
export_certificates: true
platform_key: /user/name/export_cert/pk
KEK:
- /user/name/export_cert/kek
database:
- /user/name/export_cert/db
disallow_database:
- /user/name/export_cert/dbx
delegate_to: localhost

- name: Import multiple Secure Boot certificate without applying to iDRAC.
dellemc.openmanage.idrac_secure_boot:
idrac_ip: "192.168.1.2"
idrac_user: "user"
Expand All @@ -23,7 +70,7 @@
- /root/Downloads/secureboot.pem
delegate_to: localhost

- name: Import a SecureBoot certificate and restart the server to apply it.
- name: Import a Secure Boot certificate and restart the server to apply it.
dellemc.openmanage.idrac_secure_boot:
idrac_ip: "192.168.1.2"
idrac_user: "user"
Expand Down
88 changes: 88 additions & 0 deletions plugins/module_utils/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@
HOSTNAME_REGEX = r"^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\-]*[A-Za-z0-9])$"
OME_INFO = "ApplicationService/Info"
ODATA_ID = "@odata.id"
POWER_CHECK_RETRIES = 30
POWER_CHECK_INTERVAL = 10

import time
from datetime import datetime
Expand Down Expand Up @@ -659,3 +661,89 @@ def get_lc_log_or_current_log_time(idrac, curr_time=None, lc_log_ids_list=None,
msg = "No LC log found."

return lc_log_found, msg


def expand_ipv6(ip):
sections = ip.split(':')
num_sections = len(sections)
double_colon_index = sections.index('') if '' in sections else -1
if double_colon_index != -1:
missing_sections = 8 - num_sections + 1
sections[double_colon_index:double_colon_index + 1] = ['0000'] * missing_sections
sections = [section.zfill(4) for section in sections]
expanded_ip = ':'.join(sections)
return expanded_ip


def cert_file_format_string(ip, prefix="",
postfix="",
datetime_format="%Y%m%d_%H%M%S"):
now = datetime.now()
hostname = expand_ipv6(ip).replace(":", ".")
data = f"{prefix}{hostname}_{now.strftime(datetime_format)}{postfix}"
return data


def track_power_state(idrac, base_uri, desired_state, retries=POWER_CHECK_RETRIES, interval=POWER_CHECK_INTERVAL):
count = retries
while count:
ps = get_power_state(idrac, base_uri)
if ps in desired_state:
achieved = True
break
else:
time.sleep(interval)
count = count - 1
else:
achieved = False
return achieved


def get_power_state(idrac, base_uri):
retries = 10
pstate = "Unknown"
while retries > 0:
try:
resp = idrac.invoke_request(base_uri, "GET")
pstate = resp.json_data.get("PowerState")
break
except Exception:
retries = retries - 1
return pstate


def power_act_host(idrac, system_uri, p_state):
try:
_resp, error_msg = {}, {}
uri, error_msg = validate_and_get_first_resource_id_uri(None, idrac, system_uri)
if error_msg:
return False
actions_uri = get_dynamic_uri(idrac, uri, 'Actions').get("#ComputerSystem.Reset", {}).get("target", '')
idrac.invoke_request(actions_uri, "POST", data={'ResetType': p_state})
p_act = True
except HTTPError:
p_act = False
return p_act


def reset_host(idrac, restart_type, system_uri, base_uri):
p_state = 'On'
ps = get_power_state(idrac, base_uri)
on_state = ["On"]
if ps in on_state:
p_state = 'GracefulShutdown'
if 'Force' in restart_type:
p_state = 'ForceOff'
p_act = power_act_host(idrac, system_uri, p_state)
if not p_act:
return False
state_achieved = track_power_state(idrac, base_uri, ["Off"])
p_state = "On"
if not state_achieved:
time.sleep(10)
p_state = "ForceRestart"
p_act = power_act_host(idrac, system_uri, p_state)
if not p_act:
return False
state_achieved = track_power_state(idrac, base_uri, on_state)
return state_achieved
Loading
Loading