Skip to content

Conversation

@amalykhi
Copy link
Contributor

@amalykhi amalykhi commented Dec 29, 2025

Fixing the error

**Type 'ConditionType' is unsupported for variable storage.
Origin:

ConditionType.DeviceUpdating**

Step 3: Testing inventory discovery...
+ ansible-playbook ./inventory_test.yml -i ./.config/flightctl/inventory.yml -e flightctl_host=https://api.192.168.0.16.nip.io:3443 -e flightctl_token=eyJhbGciOiJSUzI1NiIsImtpZCI6IjdVUzJ6akxDVzZINEFrWmhPLXdERWVRUHBaLWlzZm1wWXZ4bGt4WXVJa2sifQ.eyJhdWQiOlsiaHR0cHM6Ly9rdWJlcm5ldGVzLmRlZmF1bHQuc3ZjLmNsdXN0ZXIubG9jYWwiXSwiZXhwIjoxNzY3MDM5NzA0LCJpYXQiOjE3NjcwMTA5MDQsImlzcyI6Imh0dHBzOi8va3ViZXJuZXRlcy5kZWZhdWx0LnN2Yy5jbHVzdGVyLmxvY2FsIiwianRpIjoiZjQyZjE4MTgtY2MyZC00M2Y5LWEyMGItODgxYTkxNTRlOGY0Iiwia3ViZXJuZXRlcy5pbyI6eyJuYW1lc3BhY2UiOiJmbGlnaHRjdGwtZXh0ZXJuYWwiLCJzZXJ2aWNlYWNjb3VudCI6eyJuYW1lIjoiZmxpZ2h0Y3RsLWFkbWluIiwidWlkIjoiMjY3Nzc0YWMtN2I5Yy00ZTgwLWFmNzgtYmRiNTJlNjc4ZmVkIn19LCJuYmYiOjE3NjcwMTA5MDQsInN1YiI6InN5c3RlbTpzZXJ2aWNlYWNjb3VudDpmbGlnaHRjdGwtZXh0ZXJuYWw6ZmxpZ2h0Y3RsLWFkbWluIn0.jL4sErPSqN3fYzEq2nTo0iPlAW6plgp9av96gWThMBJaGDV-4TJbjo_kJhEK8y_jOCZyhWOnGUPNnoqSboYIrQl8JnDcOCJiJl1PqqgdVmt6MtyYUf5tPi0uJKcVxf9fB2km00pgdpC8Ape8JTCbk24cD3NYiEMzz7e9dQkN_B24jG2hjlIa73_TLLMn8GZwzThUNA0_YpVi8yp7MV2hoMvE6_d-bA9dgvWrWebqh9smG2GZEal-r3CEtrOAWOx7_52eH2NqBYjNWeDGT7gM9F4r01N-P13s-0s-3p-UisnTWKBBW-kAYi_KItuqtZwR7grBdAc-KPy7MWxdHmJwgw -e flightctl_organization=00000000-0000-0000-0000-000000000000
/usr/local/lib/python3.12/dist-packages/urllib3/connectionpool.py:1097: InsecureRequestWarning: Unverified HTTPS request is being made to host 'api.192.168.0.16.nip.io'. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#tls-warnings
  warnings.warn(
[WARNING]: Failed to parse inventory with 'auto' plugin: Type 'ConditionType' is unsupported for variable storage.
 
Failed to parse inventory with 'auto' plugin.
 
<<< caused by >>>
 
Type 'ConditionType' is unsupported for variable storage.
Origin: <unknown>
 
ConditionType.DeviceUpdating
 
[WARNING]: Failed to parse inventory with 'yaml' plugin: Plugin configuration YAML file, not YAML inventory
 
Failed to parse inventory with 'yaml' plugin.
 
<<< caused by >>>
 
Plugin configuration YAML file, not YAML inventory
Origin: <inventory plugin 'yaml' with source '/root/ansible_collections/flightctl/core/tests/output/.tmp/integration/inventory_flightctl-0m72whzu-ÅÑŚÌβŁÈ/tests/integration/targets/inventory_flightctl/.config/flightctl/inventory.yml'>
 
[WARNING]: Failed to parse inventory with 'ini' plugin: Failed to parse inventory: Invalid host pattern '---' supplied, '---' is normally a sign this is a YAML file.
 
Failed to parse inventory with 'ini' plugin.
 
<<< caused by >>>
 
Failed to parse inventory: Invalid host pattern '---' supplied, '---' is normally a sign this is a YAML file.
Origin: /root/ansible_collections/flightctl/core/tests/output/.tmp/integration/inventory_flightctl-0m72whzu-ÅÑŚÌβŁÈ/tests/integration/targets/inventory_flightctl/.config/flightctl/inventory.yml
 
[WARNING]: Unable to parse /root/ansible_collections/flightctl/core/tests/output/.tmp/integration/inventory_flightctl-0m72whzu-ÅÑŚÌβŁÈ/tests/integration/targets/inventory_flightctl/.config/flightctl/inventory.yml as an inventory source
[WARNING]: No inventory was parsed, only implicit localhost is available
[WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all'
 
PLAY [Test Inventory Discovery and Host Groups] ********************************
 
TASK [Display all inventory groups for debugging] ******************************
ok: [localhost] => {
    "msg": {
        "all_groups": [
            "all",
            "ungrouped"
        ],
        "all_hosts": []
    }
}
 
TASK [Assert all expected devices are in 'all' group] **************************
[ERROR]: Task failed: Action failed: Assertion failed
Origin: /root/ansible_collections/flightctl/core/tests/output/.tmp/integration/inventory_flightctl-0m72whzu-ÅÑŚÌβŁÈ/tests/integration/targets/inventory_flightctl/inventory_test.yml:16:11
 
14               all_hosts: "{{ groups['all'] | default([]) }}"
15
16         - name: Assert all expected devices are in 'all' group
             ^ column 11
 
fatal: [localhost]: FAILED! => {
    "assertion": "'ansible-integration-test-device' in groups['all']",
    "changed": false,
    "evaluated_to": false,
    "msg": "Assertion failed"
}
 
PLAY RECAP *********************************************************************
localhost                  : ok=1    changed=0    unreachable=0    failed=1    skipped=0    rescued=0    ignored=0

After fix

Running inventory_flightctl integration test script
+ CMD_ARGS=("$@")
+ echo 'Running inventory test with args: '
Running inventory test with args: 
++ grep -oP 'flightctl_host:\s*\K.*' ../../integration_config.yml
+ FLIGHTCTL_HOST=https://api.192.168.0.16.nip.io:3443
++ grep -oP 'flightctl_token:\s*\K.*' ../../integration_config.yml
+ FLIGHTCTL_TOKEN=eyJhbGciOiJSUzI1NiIsImtpZCI6IjdVUzJ6akxDVzZINEFrWmhPLXdERWVRUHBaLWlzZm1wWXZ4bGt4WXVJa2sifQ.eyJhdWQiOlsiaHR0cHM6Ly9rdWJlcm5ldGVzLmRlZmF1bHQuc3ZjLmNsdXN0ZXIubG9jYWwiXSwiZXhwIjoxNzY3MDM5NzA0LCJpYXQiOjE3NjcwMTA5MDQsImlzcyI6Imh0dHBzOi8va3ViZXJuZXRlcy5kZWZhdWx0LnN2Yy5jbHVzdGVyLmxvY2FsIiwianRpIjoiZjQyZjE4MTgtY2MyZC00M2Y5LWEyMGItODgxYTkxNTRlOGY0Iiwia3ViZXJuZXRlcy5pbyI6eyJuYW1lc3BhY2UiOiJmbGlnaHRjdGwtZXh0ZXJuYWwiLCJzZXJ2aWNlYWNjb3VudCI6eyJuYW1lIjoiZmxpZ2h0Y3RsLWFkbWluIiwidWlkIjoiMjY3Nzc0YWMtN2I5Yy00ZTgwLWFmNzgtYmRiNTJlNjc4ZmVkIn19LCJuYmYiOjE3NjcwMTA5MDQsInN1YiI6InN5c3RlbTpzZXJ2aWNlYWNjb3VudDpmbGlnaHRjdGwtZXh0ZXJuYWw6ZmxpZ2h0Y3RsLWFkbWluIn0.jL4sErPSqN3fYzEq2nTo0iPlAW6plgp9av96gWThMBJaGDV-4TJbjo_kJhEK8y_jOCZyhWOnGUPNnoqSboYIrQl8JnDcOCJiJl1PqqgdVmt6MtyYUf5tPi0uJKcVxf9fB2km00pgdpC8Ape8JTCbk24cD3NYiEMzz7e9dQkN_B24jG2hjlIa73_TLLMn8GZwzThUNA0_YpVi8yp7MV2hoMvE6_d-bA9dgvWrWebqh9smG2GZEal-r3CEtrOAWOx7_52eH2NqBYjNWeDGT7gM9F4r01N-P13s-0s-3p-UisnTWKBBW-kAYi_KItuqtZwR7grBdAc-KPy7MWxdHmJwgw
++ grep -oP 'flightctl_organization:\s*\K.*' ../../integration_config.yml
+ FLIGHTCTL_ORGANIZATION=00000000-0000-0000-0000-000000000000
+ mkdir -p .config/flightctl
+ cat
+ echo 'Step 1: Testing inventory plugin documentation...'
Step 1: Testing inventory plugin documentation...
+ ansible-playbook ./inventory_doc_test.yml
[WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all'

PLAY [Test Flight Control inventory plugin] ************************************

TASK [Run ansible-doc to get plugin help text] *********************************
ok: [localhost]

TASK [Assert every required phrase is present in ansible-doc output] ***********
ok: [localhost] => (item=flightctl.core.flightctl) => {
    "ansible_loop_var": "item",
    "changed": false,
    "item": "flightctl.core.flightctl",
    "msg": "All assertions passed"
}
ok: [localhost] => (item=returns ansible inventory) => {
    "ansible_loop_var": "item",
    "changed": false,
    "item": "returns ansible inventory",
    "msg": "All assertions passed"
}
ok: [localhost] => (item=flightctl_config_file) => {
    "ansible_loop_var": "item",
    "changed": false,
    "item": "flightctl_config_file",
    "msg": "All assertions passed"
}
ok: [localhost] => (item=flightctl-python-client) => {
    "ansible_loop_var": "item",
    "changed": false,
    "item": "flightctl-python-client",
    "msg": "All assertions passed"
}

PLAY RECAP *********************************************************************
localhost                  : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

+ echo 'Step 2: Setting up test resources...'
Step 2: Setting up test resources...
+ ansible-playbook ./inventory_setup_test.yml -e flightctl_host=https://api.192.168.0.16.nip.io:3443 -e flightctl_token=eyJhbGciOiJSUzI1NiIsImtpZCI6IjdVUzJ6akxDVzZINEFrWmhPLXdERWVRUHBaLWlzZm1wWXZ4bGt4WXVJa2sifQ.eyJhdWQiOlsiaHR0cHM6Ly9rdWJlcm5ldGVzLmRlZmF1bHQuc3ZjLmNsdXN0ZXIubG9jYWwiXSwiZXhwIjoxNzY3MDM5NzA0LCJpYXQiOjE3NjcwMTA5MDQsImlzcyI6Imh0dHBzOi8va3ViZXJuZXRlcy5kZWZhdWx0LnN2Yy5jbHVzdGVyLmxvY2FsIiwianRpIjoiZjQyZjE4MTgtY2MyZC00M2Y5LWEyMGItODgxYTkxNTRlOGY0Iiwia3ViZXJuZXRlcy5pbyI6eyJuYW1lc3BhY2UiOiJmbGlnaHRjdGwtZXh0ZXJuYWwiLCJzZXJ2aWNlYWNjb3VudCI6eyJuYW1lIjoiZmxpZ2h0Y3RsLWFkbWluIiwidWlkIjoiMjY3Nzc0YWMtN2I5Yy00ZTgwLWFmNzgtYmRiNTJlNjc4ZmVkIn19LCJuYmYiOjE3NjcwMTA5MDQsInN1YiI6InN5c3RlbTpzZXJ2aWNlYWNjb3VudDpmbGlnaHRjdGwtZXh0ZXJuYWw6ZmxpZ2h0Y3RsLWFkbWluIn0.jL4sErPSqN3fYzEq2nTo0iPlAW6plgp9av96gWThMBJaGDV-4TJbjo_kJhEK8y_jOCZyhWOnGUPNnoqSboYIrQl8JnDcOCJiJl1PqqgdVmt6MtyYUf5tPi0uJKcVxf9fB2km00pgdpC8Ape8JTCbk24cD3NYiEMzz7e9dQkN_B24jG2hjlIa73_TLLMn8GZwzThUNA0_YpVi8yp7MV2hoMvE6_d-bA9dgvWrWebqh9smG2GZEal-r3CEtrOAWOx7_52eH2NqBYjNWeDGT7gM9F4r01N-P13s-0s-3p-UisnTWKBBW-kAYi_KItuqtZwR7grBdAc-KPy7MWxdHmJwgw -e flightctl_organization=00000000-0000-0000-0000-000000000000
[WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all'

PLAY [1. Prepare Test Resources (Idempotent)] **********************************

TASK [Ensure test fleets exist] ************************************************
changed: [localhost] => (item={'name': 'ansible-integration-test-fleet', 'os_image': 'quay.io/osbuild/fedora-iot:39'})
changed: [localhost] => (item={'name': 'fleet-dev', 'os_image': 'quay.io/osbuild/fedora-iot:39'})
changed: [localhost] => (item={'name': 'fleet-test', 'os_image': 'quay.io/osbuild/fedora-iot:40'})
changed: [localhost] => (item={'name': 'fleet-prod', 'os_image': 'quay.io/osbuild/fedora-iot:stable'})

TASK [Ensure test devices exist] ***********************************************
changed: [localhost] => (item={'name': 'ansible-integration-test-device', 'labels': {'fleet': 'ansible-integration-test-fleet'}})
changed: [localhost] => (item={'name': 'ansible-integration-test-device-label-1', 'labels': {'machine_type': 'forklift'}})
changed: [localhost] => (item={'name': 'ansible-integration-test-device-label-2', 'labels': {'machine_type': 'forklift'}})
changed: [localhost] => (item={'name': 'device-dev-01', 'labels': {'fleet': 'fleet-dev', 'arch': 'amd64'}})
changed: [localhost] => (item={'name': 'device-dev-02', 'labels': {'fleet': 'fleet-dev', 'arch': 'arm64'}})
changed: [localhost] => (item={'name': 'device-test-01', 'labels': {'fleet': 'fleet-test', 'arch': 'amd64'}})
changed: [localhost] => (item={'name': 'device-unmanaged-01', 'labels': {'location': 'lab'}})

TASK [Wait for FlightCtl to process fleet assignments] *************************
Pausing for 10 seconds
(ctrl+C then 'C' = continue early, ctrl+C then 'A' = abort)
ok: [localhost]

TASK [Create client.yaml] ******************************************************
changed: [localhost]

PLAY RECAP *********************************************************************
localhost                  : ok=4    changed=3    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

+ echo 'Waiting for resources to be ready...'
Waiting for resources to be ready...
+ sleep 5
+ echo 'Step 3: Testing inventory discovery...'
Step 3: Testing inventory discovery...
+ ansible-playbook ./inventory_test.yml -i ./.config/flightctl/inventory.yml -e flightctl_host=https://api.192.168.0.16.nip.io:3443 -e flightctl_token=eyJhbGciOiJSUzI1NiIsImtpZCI6IjdVUzJ6akxDVzZINEFrWmhPLXdERWVRUHBaLWlzZm1wWXZ4bGt4WXVJa2sifQ.eyJhdWQiOlsiaHR0cHM6Ly9rdWJlcm5ldGVzLmRlZmF1bHQuc3ZjLmNsdXN0ZXIubG9jYWwiXSwiZXhwIjoxNzY3MDM5NzA0LCJpYXQiOjE3NjcwMTA5MDQsImlzcyI6Imh0dHBzOi8va3ViZXJuZXRlcy5kZWZhdWx0LnN2Yy5jbHVzdGVyLmxvY2FsIiwianRpIjoiZjQyZjE4MTgtY2MyZC00M2Y5LWEyMGItODgxYTkxNTRlOGY0Iiwia3ViZXJuZXRlcy5pbyI6eyJuYW1lc3BhY2UiOiJmbGlnaHRjdGwtZXh0ZXJuYWwiLCJzZXJ2aWNlYWNjb3VudCI6eyJuYW1lIjoiZmxpZ2h0Y3RsLWFkbWluIiwidWlkIjoiMjY3Nzc0YWMtN2I5Yy00ZTgwLWFmNzgtYmRiNTJlNjc4ZmVkIn19LCJuYmYiOjE3NjcwMTA5MDQsInN1YiI6InN5c3RlbTpzZXJ2aWNlYWNjb3VudDpmbGlnaHRjdGwtZXh0ZXJuYWw6ZmxpZ2h0Y3RsLWFkbWluIn0.jL4sErPSqN3fYzEq2nTo0iPlAW6plgp9av96gWThMBJaGDV-4TJbjo_kJhEK8y_jOCZyhWOnGUPNnoqSboYIrQl8JnDcOCJiJl1PqqgdVmt6MtyYUf5tPi0uJKcVxf9fB2km00pgdpC8Ape8JTCbk24cD3NYiEMzz7e9dQkN_B24jG2hjlIa73_TLLMn8GZwzThUNA0_YpVi8yp7MV2hoMvE6_d-bA9dgvWrWebqh9smG2GZEal-r3CEtrOAWOx7_52eH2NqBYjNWeDGT7gM9F4r01N-P13s-0s-3p-UisnTWKBBW-kAYi_KItuqtZwR7grBdAc-KPy7MWxdHmJwgw -e flightctl_organization=00000000-0000-0000-0000-000000000000
/usr/local/lib/python3.12/dist-packages/urllib3/connectionpool.py:1097: InsecureRequestWarning: Unverified HTTPS request is being made to host 'api.192.168.0.16.nip.io'. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#tls-warnings
  warnings.warn(

PLAY [Test Inventory Discovery and Host Groups] ********************************

TASK [Display all inventory groups for debugging] ******************************
ok: [localhost] => {
    "msg": {
        "all_groups": [
            "all",
            "ungrouped",
            "ansible_integration_test_fleet",
            "fleet_dev",
            "fleet_test",
            "forklift_machines",
            "amd64_devices",
            "arm64_devices",
            "lab_devices",
            "fleet_dev_devices",
            "fleet_test_devices",
            "integration_test_fleet_devices",
            "test_group",
            "integration_test_devices",
            "dev_amd64_devices",
            "forklift_devices_by_name"
        ],
        "all_hosts": [
            "ansible-integration-test-device",
            "device-dev-01",
            "device-dev-02",
            "device-test-01",
            "ansible-integration-test-device-label-1",
            "ansible-integration-test-device-label-2",
            "device-unmanaged-01"
        ]
    }
}

TASK [Assert all expected devices are in 'all' group] **************************
ok: [localhost] => {
    "changed": false,
    "msg": "All assertions passed"
}

TASK [Assert devices in fleet ansible-integration-test] ************************
ok: [localhost] => {
    "changed": false,
    "msg": "All assertions passed"
}

TASK [Assert forklift machines group] ******************************************
ok: [localhost] => {
    "changed": false,
    "msg": "All assertions passed"
}

TASK [Assert architecture groups] **********************************************
ok: [localhost] => {
    "changed": false,
    "msg": "All assertions passed"
}

TASK [Assert location groups] **************************************************
ok: [localhost] => {
    "changed": false,
    "msg": "All assertions passed"
}

TASK [Assert fleet field selector groups] **************************************
ok: [localhost] => {
    "changed": false,
    "msg": "All assertions passed"
}

TASK [Assert test group] *******************************************************
ok: [localhost] => {
    "changed": false,
    "msg": "All assertions passed"
}

TASK [Assert integration test devices group] ***********************************
ok: [localhost] => {
    "changed": false,
    "msg": "All assertions passed"
}

TASK [Assert mixed selector groups] ********************************************
ok: [localhost] => {
    "changed": false,
    "msg": "All assertions passed"
}

TASK [Display final inventory content summary] *********************************
ok: [localhost] => {
    "msg": {
        "custom_groups": [
            "ansible_integration_test_fleet",
            "fleet_dev",
            "fleet_test",
            "forklift_machines",
            "amd64_devices",
            "arm64_devices",
            "lab_devices",
            "fleet_dev_devices",
            "fleet_test_devices",
            "integration_test_fleet_devices",
            "test_group",
            "integration_test_devices",
            "dev_amd64_devices",
            "forklift_devices_by_name"
        ],
        "total_groups": 16,
        "total_hosts": 7
    }
}

PLAY [Clean up Test Inventory Resources] ***************************************

TASK [Delete test devices] *****************************************************
changed: [localhost] => (item=ansible-integration-test-device)
changed: [localhost] => (item=ansible-integration-test-device-label-1)
changed: [localhost] => (item=ansible-integration-test-device-label-2)
changed: [localhost] => (item=device-dev-01)
changed: [localhost] => (item=device-dev-02)
changed: [localhost] => (item=device-test-01)
changed: [localhost] => (item=device-unmanaged-01)

TASK [Delete test fleets] ******************************************************
changed: [localhost] => (item=ansible-integration-test-fleet)
changed: [localhost] => (item=fleet-dev)
changed: [localhost] => (item=fleet-test)
changed: [localhost] => (item=fleet-prod)

PLAY RECAP *********************************************************************
localhost                  : ok=13   changed=2    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

+ echo DONE
DONE

Summary by CodeRabbit

  • Bug Fixes
    • Improved handling of enumerated values in Flightctl inventory data by converting enum entries to plain strings before validation and population, preventing validation failures and ensuring consistent processing across fleet, device, and group imports while preserving existing data retrieval behavior.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link

coderabbitai bot commented Dec 29, 2025

Walkthrough

Adds a recursive helper to convert Enum values to strings and applies it when preparing device data for inventory population, ensuring Enum members are stringified before validation and insertion.

Changes

Cohort / File(s) Summary
Flightctl inventory plugin changes
plugins/inventory/flightctl.py
Imports Enum; adds helper def _convert_enums_to_strings(obj: Any) -> Any to recursively convert Enum values to strings; calls this helper when preparing device dictionaries in _populate_inventory_fleets(), _populate_inventory_devices(), and _populate_inventory_additional_groups() before validation/population.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and specifically describes the main change: adding enum-to-string conversion functionality to the Flightctl inventory plugin, directly addressing the core issue that caused the integration test failure.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

📜 Recent review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between af4ea2b and 7c7bce5.

📒 Files selected for processing (1)
  • plugins/inventory/flightctl.py
🚧 Files skipped from review as they are similar to previous changes (1)
  • plugins/inventory/flightctl.py
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: test-sanity-downstream
  • GitHub Check: test-unit-downstream
  • GitHub Check: integration-tests (stable-2.16, 3.12)

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
plugins/inventory/flightctl.py (1)

661-673: Consider preserving tuple types and handling sets.

The function correctly converts Enum values, but has two minor type-handling gaps:

  1. Tuple preservation: Lines 670-671 convert tuples to lists. While Ansible typically uses lists for variables, preserving the original type would be more accurate.
  2. Set handling: Line 408 checks for set types, but this function doesn't handle them. If a device field contains a set with Enum values, they won't be converted.
🔎 Proposed improvements
 def _convert_enums_to_strings(obj: Any) -> Any:
     """
     Recursively convert all Enum values in a data structure to their string values.
     This is needed because Ansible's inventory.set_variable() doesn't support Enum types.
     """
     if isinstance(obj, Enum):
         return obj.value
     if isinstance(obj, dict):
         return {k: _convert_enums_to_strings(v) for k, v in obj.items()}
-    if isinstance(obj, (list, tuple)):
+    if isinstance(obj, list):
         return [_convert_enums_to_strings(item) for item in obj]
+    if isinstance(obj, tuple):
+        return tuple(_convert_enums_to_strings(item) for item in obj)
+    if isinstance(obj, set):
+        return {_convert_enums_to_strings(item) for item in obj}
     return obj
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d2f5b68 and 3718c0c.

📒 Files selected for processing (1)
  • plugins/inventory/flightctl.py
🧰 Additional context used
🧠 Learnings (5)
📓 Common learnings
Learnt from: SiddarthR56
Repo: flightctl/flightctl-ansible PR: 32
File: tests/integration/targets/flightctl_certificate_management/tasks/certificate-signing-approval.yml:48-49
Timestamp: 2025-04-24T17:24:38.607Z
Learning: The assertions checking CSR approval status in tests/integration/targets/flightctl_certificate_management/tasks/certificate-signing-approval.yml are temporarily commented out pending the merge of PR #1104 (https://github.com/flightctl/flightctl/pull/1104) which addresses an issue with CSR approval endpoints. These should be re-enabled once that PR is merged.
Learnt from: gshilin-sdb
Repo: flightctl/flightctl-ansible PR: 31
File: plugins/inventory/flightctl.py:694-712
Timestamp: 2025-04-28T12:30:07.851Z
Learning: In the flightctl.core.flightctl inventory plugin, logging errors via display.error() and continuing execution is preferred over raising exceptions for non-critical configuration issues, to maintain plugin resilience and allow it to function with partial data.
Learnt from: gshilin-sdb
Repo: flightctl/flightctl-ansible PR: 34
File: plugins/inventory/flightctl.py:288-291
Timestamp: 2025-05-06T08:44:35.361Z
Learning: In flightctl.py inventory plugin, authentication credentials (access_token or username/password) are only required when SSL verification is enabled (verify_ssl=True). When SSL verification is disabled, the system allows unauthenticated requests by design.
Learnt from: gshilin-sdb
Repo: flightctl/flightctl-ansible PR: 31
File: plugins/inventory/flightctl.py:0-0
Timestamp: 2025-04-22T13:45:41.777Z
Learning: The _get_data function in flightctl.py inventory plugin is intentionally designed to fetch ALL devices/fleets without filtering via label_selector or field_selector parameters. Filtering is handled by the plugin's logic after retrieving the complete dataset.
Learnt from: gshilin-sdb
Repo: flightctl/flightctl-ansible PR: 31
File: plugins/inventory/flightctl.py:232-251
Timestamp: 2025-04-28T11:44:07.573Z
Learning: In the flightctl inventory plugin, authentication validation (token/username/password) is only required when SSL verification is enabled (verify_ssl=True). This is intentional behavior per the author's design.
Learnt from: gshilin-sdb
Repo: flightctl/flightctl-ansible PR: 31
File: plugins/inventory/flightctl.py:0-0
Timestamp: 2025-04-22T13:45:42.302Z
Learning: The _get_data helper function in plugins/inventory/flightctl.py only accepts two parameters: list_func (a callable) and an optional limit parameter. It doesn't support directly passing additional parameters like label_selector or field_selector to the API functions.
📚 Learning: 2025-04-28T12:30:07.851Z
Learnt from: gshilin-sdb
Repo: flightctl/flightctl-ansible PR: 31
File: plugins/inventory/flightctl.py:694-712
Timestamp: 2025-04-28T12:30:07.851Z
Learning: In the flightctl.core.flightctl inventory plugin, logging errors via display.error() and continuing execution is preferred over raising exceptions for non-critical configuration issues, to maintain plugin resilience and allow it to function with partial data.

Applied to files:

  • plugins/inventory/flightctl.py
📚 Learning: 2025-04-22T13:45:41.777Z
Learnt from: gshilin-sdb
Repo: flightctl/flightctl-ansible PR: 31
File: plugins/inventory/flightctl.py:0-0
Timestamp: 2025-04-22T13:45:41.777Z
Learning: The _get_data function in flightctl.py inventory plugin is intentionally designed to fetch ALL devices/fleets without filtering via label_selector or field_selector parameters. Filtering is handled by the plugin's logic after retrieving the complete dataset.

Applied to files:

  • plugins/inventory/flightctl.py
📚 Learning: 2025-05-06T08:44:35.361Z
Learnt from: gshilin-sdb
Repo: flightctl/flightctl-ansible PR: 34
File: plugins/inventory/flightctl.py:288-291
Timestamp: 2025-05-06T08:44:35.361Z
Learning: In flightctl.py inventory plugin, authentication credentials (access_token or username/password) are only required when SSL verification is enabled (verify_ssl=True). When SSL verification is disabled, the system allows unauthenticated requests by design.

Applied to files:

  • plugins/inventory/flightctl.py
📚 Learning: 2025-04-28T11:44:07.573Z
Learnt from: gshilin-sdb
Repo: flightctl/flightctl-ansible PR: 31
File: plugins/inventory/flightctl.py:232-251
Timestamp: 2025-04-28T11:44:07.573Z
Learning: In the flightctl inventory plugin, authentication validation (token/username/password) is only required when SSL verification is enabled (verify_ssl=True). This is intentional behavior per the author's design.

Applied to files:

  • plugins/inventory/flightctl.py
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: test-unit-downstream
  • GitHub Check: test-sanity-downstream
  • GitHub Check: integration-tests (stable-2.16, 3.12)
🔇 Additional comments (6)
plugins/inventory/flightctl.py (6)

45-48: LGTM!

The organization option is clearly documented and follows the established pattern for other configuration options.


139-139: LGTM!

The Enum import is necessary for the new _convert_enums_to_strings helper function and properly placed in the imports section.


323-324: LGTM!

The Enum-to-string conversion is correctly applied after to_dict() conversion and before device validation. The comment clearly explains the purpose.


341-342: LGTM!

Consistent application of Enum conversion in the main device population path.


389-390: LGTM!

Enum conversion is consistently applied in both static and keyed additional group processing paths, ensuring complete coverage across all inventory population mechanisms.

Also applies to: 402-403


281-283: No action needed—Configuration.organization is a valid attribute.

The organization option parsing and assignment are correct. The attribute is documented in the plugin's options (lines 45-47), and the setting pattern on line 303 matches the established approach used for other optional configuration attributes like request_timeout and verify_ssl.

@amalykhi amalykhi changed the title NO-ISSUE: fix inventory test NO-ISSUE: Add organization option and Enum-to-string conversion to Flightctl inventory plugin Dec 29, 2025
@amalykhi amalykhi requested a review from SiddarthR56 December 29, 2025 13:46
@amalykhi amalykhi changed the title NO-ISSUE: Add organization option and Enum-to-string conversion to Flightctl inventory plugin NO-ISSUE: Add Enum-to-string conversion to Flightctl inventory plugin Dec 29, 2025
@amalykhi amalykhi changed the title NO-ISSUE: Add Enum-to-string conversion to Flightctl inventory plugin EDM-2929: Add Enum-to-string conversion to Flightctl inventory plugin Dec 29, 2025
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
plugins/inventory/flightctl.py (1)

661-673: Well-implemented solution to the Ansible Enum limitation.

The recursive helper correctly converts Enum values to strings across all nested data structures. The docstring clearly explains the purpose, and the implementation handles the common cases (dict, list, tuple, Enum).

Optional: Note on tuple-to-list conversion

The function converts tuples to lists (line 671), which changes immutability semantics. This is acceptable since Ansible inventory variables expect JSON-serializable types, but if preserving tuple types is desired, you could modify line 671:

     if isinstance(obj, (list, tuple)):
-        return [_convert_enums_to_strings(item) for item in obj]
+        converted = [_convert_enums_to_strings(item) for item in obj]
+        return type(obj)(converted) if isinstance(obj, tuple) else converted

However, this is likely unnecessary for the inventory use case.

📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3718c0c and af4ea2b.

📒 Files selected for processing (1)
  • plugins/inventory/flightctl.py
🧰 Additional context used
🧠 Learnings (2)
📚 Learning: 2025-04-22T13:45:41.777Z
Learnt from: gshilin-sdb
Repo: flightctl/flightctl-ansible PR: 31
File: plugins/inventory/flightctl.py:0-0
Timestamp: 2025-04-22T13:45:41.777Z
Learning: The _get_data function in flightctl.py inventory plugin is intentionally designed to fetch ALL devices/fleets without filtering via label_selector or field_selector parameters. Filtering is handled by the plugin's logic after retrieving the complete dataset.

Applied to files:

  • plugins/inventory/flightctl.py
📚 Learning: 2025-04-28T12:30:07.851Z
Learnt from: gshilin-sdb
Repo: flightctl/flightctl-ansible PR: 31
File: plugins/inventory/flightctl.py:694-712
Timestamp: 2025-04-28T12:30:07.851Z
Learning: In the flightctl.core.flightctl inventory plugin, logging errors via display.error() and continuing execution is preferred over raising exceptions for non-critical configuration issues, to maintain plugin resilience and allow it to function with partial data.

Applied to files:

  • plugins/inventory/flightctl.py
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: test-unit-downstream
  • GitHub Check: test-sanity-downstream
  • GitHub Check: integration-tests (stable-2.16, 3.12)
🔇 Additional comments (2)
plugins/inventory/flightctl.py (2)

139-139: LGTM!

The Enum import is necessary for the new helper function and correctly placed with other standard library imports.


323-324: Excellent consistent application across all device processing paths.

The enum-to-string conversion is correctly applied at all four locations where device data enters the inventory:

  1. Fleet devices (lines 323-324)
  2. Direct devices (lines 341-342)
  3. Additional groups (static) (lines 389-390)
  4. Additional groups (keyed) (lines 402-403)

The consistent pattern—convert to dict, convert enums, then validate—ensures that all devices have Enum values converted to strings before being stored in Ansible inventory variables. The explanatory comments are helpful and uniform across all locations.

Also applies to: 341-342, 389-390, 402-403

@amalykhi amalykhi merged commit 03ae8b2 into flightctl:main Dec 30, 2025
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants