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