diff --git a/python/understack-workflows/tests/test_helpers.py b/python/understack-workflows/tests/test_helpers.py index fd4df778d..e5eef2820 100644 --- a/python/understack-workflows/tests/test_helpers.py +++ b/python/understack-workflows/tests/test_helpers.py @@ -5,9 +5,28 @@ import pytest +from understack_workflows.helpers import int_or_str from understack_workflows.helpers import parser_nautobot_args +@pytest.mark.parametrize( + ("value", "expected"), + [ + ("123", 123), + ("0", 0), + ("-5", -5), + ("abc", "abc"), + ("12ab", "12ab"), + ("", ""), + ("1.5", "1.5"), + ], +) +def test_int_or_str(value, expected): + result = int_or_str(value) + assert result == expected + assert type(result) is type(expected) + + @pytest.mark.parametrize( ("arg_list", "context", "expected_url"), [ diff --git a/python/understack-workflows/understack_workflows/helpers.py b/python/understack-workflows/understack_workflows/helpers.py index e65be392f..ce87cb1bf 100644 --- a/python/understack-workflows/understack_workflows/helpers.py +++ b/python/understack-workflows/understack_workflows/helpers.py @@ -56,6 +56,14 @@ def setup_logger(level: int = logging.DEBUG) -> None: ) +def int_or_str(value: str) -> int | str: + """Attempts to convert a value to an integer.""" + try: + return int(value) + except ValueError: + return value + + def boolean_args(val): normalised = str(val).upper() if normalised in ["YES", "TRUE", "T", "1"]: diff --git a/python/understack-workflows/understack_workflows/ironic_node.py b/python/understack-workflows/understack_workflows/ironic_node.py index 00c0bfa34..4eb836b67 100644 --- a/python/understack-workflows/understack_workflows/ironic_node.py +++ b/python/understack-workflows/understack_workflows/ironic_node.py @@ -42,7 +42,7 @@ def create_or_update( bmc: Bmc, name: str, manufacturer: str, - external_cmdb_id: str | None = None, + external_cmdb_id: int | str | None = None, ) -> Node: """Find-or-create Node by name, update attributes, set state to Manageable. @@ -110,7 +110,7 @@ def update_ironic_node( name, driver, inspect_interface, - external_cmdb_id: str | None = None, + external_cmdb_id: int | str | None = None, ): updates = [ f"name={name}", @@ -139,7 +139,7 @@ def create_ironic_node( name: str, driver: str, inspect_interface: str, - external_cmdb_id: str | None = None, + external_cmdb_id: int | str | None = None, ) -> Node: node_data = { "name": name, diff --git a/python/understack-workflows/understack_workflows/main/enroll_server.py b/python/understack-workflows/understack_workflows/main/enroll_server.py index bff6865f5..63565b519 100644 --- a/python/understack-workflows/understack_workflows/main/enroll_server.py +++ b/python/understack-workflows/understack_workflows/main/enroll_server.py @@ -6,6 +6,7 @@ from ironicclient.v1.node import Node +from understack_workflows import helpers from understack_workflows import ironic_node from understack_workflows.bmc import Bmc from understack_workflows.bmc import bmc_for_ip_address @@ -15,7 +16,6 @@ from understack_workflows.bmc_credentials import set_bmc_password from understack_workflows.bmc_hostname import bmc_set_hostname from understack_workflows.bmc_settings import update_dell_drac_settings -from understack_workflows.helpers import setup_logger from understack_workflows.raid import configure_raid logger = logging.getLogger(__name__) @@ -57,7 +57,7 @@ def main() -> None: - Transition the node to the 'available' state (implies cleaning). """ - setup_logger() + helpers.setup_logger() args = argument_parser().parse_args() enroll( @@ -74,7 +74,7 @@ def enroll( firmware_update: bool, raid_configure: bool, old_password: str | None, - external_cmdb_id: str | None = None, + external_cmdb_id: int | str | None = None, ) -> None: logger.info("Starting enroll workflow for bmc_ip_address=%s", ip_address) @@ -221,6 +221,7 @@ def argument_parser(): ) parser.add_argument( "--external-cmdb-id", + type=helpers.int_or_str, required=False, default="", help="External CMDB ID for RXDB integration",