From 30d95f26e3dd3e075fd7ece9d328174853a2dd76 Mon Sep 17 00:00:00 2001 From: ccoueffe Date: Mon, 24 Nov 2025 14:38:18 +0100 Subject: [PATCH 1/2] add new variables discovery_username, discovery_password Signed-off-by: ccoueffe --- plugins/action/common/get_credentials.py | 27 +++++++++++++ .../files/rules/common/312_env_variable.py | 40 +++++++++++++++++++ 2 files changed, 67 insertions(+) create mode 100644 roles/validate/files/rules/common/312_env_variable.py diff --git a/plugins/action/common/get_credentials.py b/plugins/action/common/get_credentials.py index 9e93ef3cc..f36391f57 100644 --- a/plugins/action/common/get_credentials.py +++ b/plugins/action/common/get_credentials.py @@ -79,10 +79,14 @@ def run(self, tmp=None, task_vars=None): key_username = 'ndfc_switch_username' key_password = 'ndfc_switch_password' + key_discovery_username = 'ndfc_switch_discovery_username' + key_discovery_password = 'ndfc_switch_discovery_password' ndfc_host_name = task_vars['inventory_hostname'] username = task_vars['hostvars'][ndfc_host_name].get(key_username, '') password = task_vars['hostvars'][ndfc_host_name].get(key_password, '') + discovery_username = task_vars['hostvars'][ndfc_host_name].get(key_discovery_username, '') + discovery_password = task_vars['hostvars'][ndfc_host_name].get(key_discovery_password, '') # Fail if username and password are not set if username == '' or password == '': @@ -129,5 +133,28 @@ def run(self, tmp=None, task_vars=None): new_device['password'] = password display.vvv(f"No individual credentials found in model data for device {device_ip}. Using group_vars credentials.") + # Handle discovery credentials if applicable + if 'poap' in new_device and new_device['poap']: + discovery_user = new_device['poap'][0].get('discovery_username') + discovery_pass = new_device['poap'][0].get('discovery_password') + + # Check for placeholder values indicating new credentials are needed for discovery + is_placeholder = ( + discovery_user == 'PLACE_HOLDER_USERNAME' or + discovery_pass == 'PLACE_HOLDER_PASSWORD' + ) + if is_placeholder: + # Use group_vars discovery credentials + if discovery_username == '' or discovery_password == '': + display.warning( + f"No discovery credentials found for new user in group_vars for device {device_ip}. " + f"Skipping discovery credentials assignment and fallback to default behavior." + ) + new_device['poap'][0].pop('discovery_username', None) + new_device['poap'][0].pop('discovery_password', None) + else: + new_device['poap'][0]['discovery_username'] = discovery_username + new_device['poap'][0]['discovery_password'] = discovery_password + results['updated_inv_list'] = updated_inv_list return results diff --git a/roles/validate/files/rules/common/312_env_variable.py b/roles/validate/files/rules/common/312_env_variable.py new file mode 100644 index 000000000..cb573c9f0 --- /dev/null +++ b/roles/validate/files/rules/common/312_env_variable.py @@ -0,0 +1,40 @@ +class Rule: + id = "312" + description = "Verify NDFC_SW_DISCOVERY_PASSWORD environment variable minimum length" + severity = "HIGH" + + @classmethod + def match(cls, data_model): + results = [] + import os + # Check if NDFC_SW_DISCOVERY_PASSWORD environment variable is declared + env_var_name = 'NDFC_SW_DISCOVERY_PASSWORD' + + # Use get() to safely retrieve the variable (returns None if not declared) + password = os.environ.get(env_var_name) + + # Handle case where variable is not declared or is empty + if password is None: + results.append( + f"Environment variable '{env_var_name}' is not declared. " + "This variable is required for switch discovery operations." + ) + return results + + if password == '': + results.append( + f"Environment variable '{env_var_name}' is declared but empty. " + "A non-empty password is required." + ) + return results + + # Check minimum password length (8 characters) + min_length = 8 + if len(password) < min_length: + results.append( + f"Environment variable '{env_var_name}' has length of {len(password)} characters. " + f"Minimum required length is {min_length} characters." + ) + return results + + return results From 6b568c4e9b1694dcc2fe066a38c9c7f6595a95f6 Mon Sep 17 00:00:00 2001 From: ccoueffe Date: Tue, 25 Nov 2025 08:55:15 +0100 Subject: [PATCH 2/2] add jinja template updated Signed-off-by: ccoueffe --- .../templates/ndfc_inventory/common/fabric_inventory.j2 | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/roles/dtc/common/templates/ndfc_inventory/common/fabric_inventory.j2 b/roles/dtc/common/templates/ndfc_inventory/common/fabric_inventory.j2 index 01ab73f65..65f9bc902 100644 --- a/roles/dtc/common/templates/ndfc_inventory/common/fabric_inventory.j2 +++ b/roles/dtc/common/templates/ndfc_inventory/common/fabric_inventory.j2 @@ -27,6 +27,10 @@ hostname: {{ switch['name'] }} model: {{ pdata['model'] }} version: {{ pdata['version'] }} +{% if switch['poap'].discovery_new_user is defined and switch['poap'].discovery_new_user %} + discovery_username: PLACE_HOLDER_USERNAME + discovery_password: PLACE_HOLDER_PASSWORD +{% endif %} config_data: modulesModel: {{ pdata['modulesModel'] }} gateway: {{ pdata['gateway'] }} @@ -43,6 +47,10 @@ - preprovision_serial: {{ switch['poap']['preprovision']['serial_number'] }} model: {{ switch['poap']['preprovision']['model'] }} version: {{ switch['poap']['preprovision']['version'] }} +{% if switch['poap'].discovery_new_user is defined and switch['poap'].discovery_new_user %} + discovery_username: PLACE_HOLDER_USERNAME + discovery_password: PLACE_HOLDER_PASSWORD +{% endif %} config_data: modulesModel: {{ switch['poap']['preprovision']['modulesModel'] }} gateway: {{ switch['management']['default_gateway_v4'] | ansible.utils.ipaddr('address') }}/{{ switch['management']['subnet_mask_ipv4'] }}