That did the trick! :)
Strange that it worked before because I'm fairly certain we didn't have
this line in our code but apparently, now we need it.
Is this perhaps a change in the way API calls are handled?

Kind regards,

Jeroen Kleijer

On Sat, Nov 16, 2024 at 1:16 PM Wei ZHOU <ustcweiz...@gmail.com> wrote:

> Can you add a param to the api and retry ?
>
> sessionkey: {{ session_key }}
>
>
>
> On Saturday, November 16, 2024, Jeroen Kleijer <jeroen.klei...@gmail.com>
> wrote:
>
> > 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