Hi all,

We've been using ACS (4.19 series) in our test and development environment
for the last 6 months or so and written some ansible code to help with the
deployment. For some parts we can use the native ngine_io.cloudstack
modules, for others where we have to use the API calls made available to
us, we have to use the modules ansible.builtin.uri.

In order to use the uri module, we figured out that it needs a session_key
and jsession_id so we authenticate with ACS:
- name: Authenticate with Cloudstack
  ansible.builtin.uri:
    url: "{{ cloudstack_url }}"
    method: POST
    body_format: form-urlencoded
    body:
      command: "login"
      username: "{{ admin_username }}"
      password: "{{ vault_admin_password }}"
      response: "json"
    return_content: true
  register: login_response

and get the response back in login_response:
login_response": {
        "ansible_facts": {
            "discovered_interpreter_python": "/usr/libexec/platform-python"
        },
        "attempts": 1,
        "changed": false,
        "connection": "close",
        "content":
"{\"loginresponse\":{\"username\":\"admin\",\"userid\":\"b3160af1-a352-11ef-8180-525400a326e8\",\"domainid\":\"9ad63ce2-a352-11ef-8180-525400a326e8\",\"timeout\":1800,\"account\":\"admin\",\"firstname\":\"admin\",\"lastname\":\"cloud\",\"type\":\"1\",\"timezone\":\"UTC\",\"timezoneoffset\":\"0.0\",\"registered\":\"false\",\"sessionkey\":\"ViKNXl3dPKQRcMKXvAtfaOdC8RE\",\"is2faenabled\":\"false\",\"is2faverified\":\"true\",\"issuerfor2fa\":\"CloudStack\"}}",
        "content_length": "397",
        "content_security_policy": "1, default-src=none, script-src=self,
connect-src=self, img-src=self, style-src=self",
        "content_type": "application/json;charset=utf-8",
        "cookies": {
            "JSESSIONID": "node01ey4k6vgfkn7s1oyy83nqivzzh33.node0",
            "sessionkey": "ViKNXl3dPKQRcMKXvAtfaOdC8RE"
        },
        "cookies_string":
"JSESSIONID=node01ey4k6vgfkn7s1oyy83nqivzzh33.node0;
sessionkey=ViKNXl3dPKQRcMKXvAtfaOdC8RE",
        "elapsed": 0,
        "expires": "Thu, 01 Jan 1970 00:00:00 GMT",
        "failed": false,
        "json": {
            "loginresponse": {
                "account": "admin",
                "domainid": "<redacted>",
                "firstname": "admin",
                "is2faenabled": "false",
                "is2faverified": "true",
                "issuerfor2fa": "CloudStack",
                "lastname": "cloud",
                "registered": "false",
                "sessionkey": "<redacted>",
                "timeout": 1800,
                "timezone": "UTC",
                "timezoneoffset": "0.0",
                "type": "1",
                "userid": "<redacted>",
                "username": "admin"
            }
        },
        "msg": "OK (397 bytes)",
        "redirected": false,
        "set_cookie": "JSESSIONID=<redacted>; Path=/client,
sessionkey=<redacted>;HttpOnly;SameSite=Lax",
        "status": 200,
        "url": "<redacted>",
        "vary": "Accept-Encoding, User-Agent",
        "x_content_type_options": "nosniff",
        "x_xss_protection": "1;mode=block"
    }
}

We grab the sessionkey and jsession_id from this and then pass it along
anytime we want to use the API via Ansible. For example:
- name: Get API and Secret Key for admin
  ansible.builtin.uri:
    url: "{{ cloudstack_url }}"
    method: POST
    body_format: form-urlencoded
    headers:
      Cookie: "sessionkey={{ session_key }}; JSESSIONID={{ jsession_id }}"
    body:
      command: "getUserKeys"
      id: "{{ login_response['json']['loginresponse']['userid'] }}"
      response: json
    return_content: true

Now this code worked perfectly fine, but when we now try to deploy it in
our QA environment, the task "Get API and Secret Key for admin" fails with
the message:
TASK [authenticate-acs : Get API and Secret Key for admin]
*****************************************************************************************************************************
fatal: [<redacted>]: FAILED! => {"changed": false, "connection": "close",
"content":
"{\"getuserkeysresponse\":{\"uuidList\":[],\"errorcode\":401,\"errortext\":\"unable
to verify user credentials\"}}", "content_length": "103",
"content_security_policy": "style-src=self", "content_type":
"application/json;charset=utf-8", "elapsed": 0, "json":
{"getuserkeysresponse": {"errorcode": 401, "errortext": "unable to verify
user credentials", "uuidList": []}}, "msg": "Status code was 401 and not
[200]: HTTP Error 401: Unauthorized", "redirected": false, "status": 401,
"url": "<redacted>", "x_content_type_options": "nosniff",
"x_xss_protection": "1;mode=block"}

We didn't make any modifications to this piece of code so we're quite
surprised that it reacts this way when it worked perfectly fine before in
our test and development environments.

Has anyone run into this before and if so, were you able work around this?

Kind regards,

Jeroen

Reply via email to