ansible-collections / community.general

Ansible Community General Collection
https://galaxy.ansible.com/ui/repo/published/community/general/
GNU General Public License v3.0
830 stars 1.53k forks source link

xcc_redfish_command: Returned value not as useful as using uri module #8279

Open smalenfant opened 6 months ago

smalenfant commented 6 months ago

Summary

When I try to use the community.general.xcc_redfish_command to InsertMedia, it doesn't quite work against an SR635 server. I had to revert to using the uri module and that starting working correctly. I tried to migrate back to the xcc_redfish_command with Raw/PostResource but the return values are not sent back in the results.

This was tested with Lenovo SR635 with BMC version 7.27

Steps:

Issue Type

Bug Report

Component Name

xcc_redfish_command

Ansible Version

$ ansible --version
ansible [core 2.16.6]
  config file = None
  configured module search path = ['/Users/smalenfa/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /Users/smalenfa/sandbox/cdn-provisioning/provisioning/venv/lib/python3.12/site-packages/ansible
  ansible collection location = /Users/smalenfa/.ansible/collections:/usr/share/ansible/collections
  executable location = /Users/smalenfa/sandbox/cdn-provisioning/provisioning/venv/bin/ansible
  python version = 3.12.3 (main, Apr  9 2024, 08:09:14) [Clang 15.0.0 (clang-1500.3.9.4)] (/Users/smalenfa/sandbox/cdn-provisioning/provisioning/venv/bin/python3.12)
  jinja version = 3.1.3
  libyaml = True

Community.general Version

$ ansible-galaxy collection list community.general
# /opt/homebrew/lib/python3.11/site-packages/ansible_collections
Collection        Version
----------------- -------
community.general 8.6.0  

Configuration

$ ansible-config dump --only-changed

OS / Environment

RHEL9, OSX

Steps to Reproduce

    - name: Insert Virtual Media
      community.general.xcc_redfish_command:
        category: Raw
        command: PostResource
        baseuri: "{{ baseuri }}"
        username: "{{ username }}"
        password: "{{ password }}"
        resource_uri: "/redfish/v1/Managers/Self/VirtualMedia/CD1/Actions/VirtualMedia.InsertMedia"
        request_body:
          Image: "https://10.10.10.10/files/{{ inventory_hostname }}.iso"
          TransferProtocolType: HTTPS
          UserName: test
          Password: test
      register: res_insert

    - name: Wait until Virtual Media is attached (when using uri module)
      ansible.builtin.uri:
        url: "{{ _task_url }}"
        method: GET
        user: "{{ username }}"
        password: "{{ password }}"
        validate_certs: false
      vars:
        _task_url: "{{ res_insert.location }}"
      register: _uri_out
      until: _uri_out.json.TaskState == "Completed"
      retries: 12
      delay: 5

Expected Results

When using the URI module, we actually get useful information about the task created by the command:

    - name: Insert Virtual Media
      ansible.builtin.uri:
        url: "https://{{ baseuri }}/redfish/v1/Managers/Self/VirtualMedia/CD1/Actions/VirtualMedia.InsertMedia"
        method: POST
        user: "{{ username }}"
        password: "{{ password }}"
        body_format: json
        body:
          Image: "https://10.10.10.10/files/{{ inventory_hostname }}.iso"
          TransferProtocolType: HTTPS
          UserName: test
          Password: test
        validate_certs: false
        status_code:
          - 202
      register: res_insert

Output:

TASK [Debug Insert Virtual Media] ************************************************************************************************************************************************************
ok: [dklbcdedgel02.coxlab.net] => {
    "res_insert": {
        "access_control_allow_credentials": "true",
        "access_control_allow_headers": "X-Auth-Token",
        "access_control_allow_origin": "*",
        "access_control_expose_headers": "X-Auth-Token",
        "allow": "POST",
        "cache_control": "no-cache, must-revalidate",
        "changed": false,
        "connection": "close",
        "content_length": "233",
        "content_type": "application/json; charset=UTF-8",
        "cookies": {},
        "cookies_string": "",
        "date": "Thu, 25 Apr 2024 00:33:03 GMT",
        "elapsed": 4,
        "etag": "\"1714005183\"",
        "failed": false,
        "json": {
            "@odata.context": "/redfish/v1/$metadata#Task.Task",
            "@odata.id": "/redfish/v1/TaskService/Tasks/22",
            "@odata.type": "#Task.v1_4_2.Task",
            "Description": "Task for InsertMedia Action",
            "Id": "22",
            "Name": "InsertMedia Action",
            "TaskState": "New"
        },
        "link": "<http://redfish.dmtf.org/schemas/v1/Task.v1_4_2.json>, </redfish/v1/TaskService/Tasks/22>; path=",
        "location": "https://fqdn/redfish/v1/TaskService/Tasks/22",
        "msg": "OK (233 bytes)",
        "odata_version": "4.0",
        "prefer": "respond-async; wait=1",
        "redirected": false,
        "server": "AMI MegaRAC Redfish Service",
        "status": 202,
        "url": "https://fqdn/redfish/v1/Managers/Self/VirtualMedia/CD1/Actions/VirtualMedia.InsertMedia"
    }
}

Actual Results

TASK [Insert Virtual Media] ******************************************************************************************************************************************************************
changed: [dklbcdedgel02.coxlab.net] => {"changed": true, "msg": "Action was successful"}

TASK [Debug Insert Virtual Media] ************************************************************************************************************************************************************
ok: [dklbcdedgel02.coxlab.net] => {
    "res_insert": {
        "changed": true,
        "failed": false,
        "msg": "Action was successful"
    }
}

Code of Conduct

ansibullbot commented 6 months ago

Files identified in the description:

If these files are incorrect, please update the component name section of the description or use the !component bot command.

click here for bot help

ansibullbot commented 6 months ago

cc @panyy3 @renxulei click here for bot help

panyy3 commented 6 months ago

@smalenfant Does this issue only occur on Lenovo SR635? Have ever meet this issue on other platforms?

smalenfant commented 6 months ago

@smalenfant Does this issue only occur on Lenovo SR635? Have ever meet this issue on other platforms?

I think this would be applicable to any server. This is about the returned information, not necessarily a bug. The problem with inserting a Virtual Media is that it is not accessible right away and other API calls are required to verify the media is ready (or failed). I don't thing it is possible to check the Virtual Media for a pending task (unless you want to parse all the existing pending tasks).

I have been unsuccessful using the pre-written virtual_media command from this module but I'll give it a try again. I figured out that one can't use FQDN and has to be IP address with TLS for HTTPS, which makes it really inconvenient. But that would be a bug on the XCC controller (or limitation).

smalenfant commented 6 months ago

In addition, looks like the response code of 202 tells us something:

The 202 Accepted status code means that the request has been accepted for processing, but the processing has not been finished yet. The request may or may not be completed when the processing eventually takes place.

Maybe if a 202 is returned, the location field should be returned as well.

smalenfant commented 6 months ago

I've tried the virtual_media option:

    - name: Insert Virtual Media (xcc_redfish)
      community.general.xcc_redfish_command:
        category: Manager
        command: VirtualMediaInsert
        baseuri: "{{ baseuri }}"
        username: "{{ username }}"
        password: "{{ password }}"
        virtual_media:
          image_url: "https://10.10.10.10/files/{{ inventory_hostname }}.iso"
          media_types:
            - CD
          transfer_protocol_type: HTTPS
          username: test
          password: test

And the returned response was:

"msg": "HTTP Error 400 on POST request to 'https://fqdn/redfish/v1/Managers/Self/VirtualMedia/CD1/Actions/VirtualMedia.InsertMedia', extended message: 'The property Password is a required property and must be included in the request.'"

In raise an exception in the modules and got the following which Password was not included.

line 2732, in _insert_virt_media_payload\nException: {'Image': 'https://10.10.10.10/files/dklbcdedgel02.coxlab.net.iso', 'Inserted': True, 'WriteProtected': True, 'UserName': 'test', 'TransferProtocolType': 'HTTPS'}\n"
smalenfant commented 6 months ago

I've also tested this to make the virtual_media to work. This is because the password isn't part of the data coming back, it gets discarded. I added manually and that inserted the media. Password is required even if not used for HTTPS (at least my service):

    def _insert_virt_media_payload(options, param_map, data, ai):
        payload = {
            'Image': options.get('image_url')
        }
        for param, option in param_map.items():
            if param is "Password": 
                payload[param] = options.get(option)
            if options.get(option) is not None and param in data:
                allowable = ai.get(param, {}).get('AllowableValues', [])
                if allowable and options.get(option) not in allowable:
                    return {'ret': False,
                            'msg': "Value '%s' specified for option '%s' not "
                                   "in list of AllowableValues %s" % (
                                       options.get(option), option,
                                       allowable)}
                payload[param] = options.get(option)
        # raise Exception(payload)
        return payload

The Password option is in the allowable values. But the code can't get there due to the previous conditional about param in data.

panyy3 commented 6 months ago

@smalenfant Thanks for reporting issues about task location not return and password not inclueded. We will fix it in future.