2

I am trying to get VM information from VMware vCenter v6.5 with PHP 7. I am receiving error code 400 from curl_getinfo.

I copied the code for this from this post: VCenter ReST API authentication

I've tried this from command line and am able get a session ID, so I know that the server is sending information back as it should, just not to the PHP web page.

Reference for following command: https://communities.vmware.com/thread/556377

curl -X POST --header 'Content-Type: application/json' --header 'Accept: application/json' --header 'vmware-use-header-authn: test' --header 'vmware-api-session-id: null' -u 'administrator@vsphere.local' 'https://vcenter.mydomain.local/rest/com/vmware/cis/session'
<?php
$ch = curl_init();

curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_URL,'https://vcenter.mydomain.local/rest/com/vmware/cis/session');
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_USERPWD, 'administrator@vsphere.local:Passw0rd');
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC );
$headers = array(
'Content-Type: application/json',
'Accept: application/json',
'vmware-use-header-authn: test',
'vmware-api-session-id: null',
'Expect:'
);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLINFO_HEADER_OUT, true);

$out = json_decode(curl_exec($ch));

if(!curl_exec($ch)){
die('Error: "' . curl_error($ch) . '" - Code: ' . curl_errno($ch));
}

$info = curl_getinfo($ch);
echo "<p>CURL URL: " . $info['url'];
echo "<p><font color=green>CURL Dump: <br>";
echo '<pre>';
var_dump($info);
echo "</pre>\n";
echo "<p>OUT:<br>";
var_dump($out);
if ($out === false) {
   echo 'Curl Error: ' . curl_error($ch);
   exit;
}
$sid = $out->value;

echo "<br>SID: " . $sid;

curl_close($ch);
?>

I expect the output from $out->value will be a session ID, instead I get NULL. Grateful for any help, thanks!

Worthwelle
  • 1,244
  • 1
  • 16
  • 19
SuperDogStar
  • 21
  • 1
  • 3
  • did you ever solved this ? – VladoPortos Sep 28 '20 at 14:53
  • @VladoPortos - Yes, I was able to get this working perfectly. I believe it was due to a problem with the headers I was using. – SuperDogStar Sep 29 '20 at 15:23
  • same I got it working... now I'm banging my head with issue trying to request ticket from /mob ...method=acquireTicket it is failing with "Possible XSRF (Cross-Site Request Forgery) detected" and I can't get pass that :( – VladoPortos Sep 29 '20 at 16:16
  • @VladoPortos - did you ever get this sorted as I am hitting the same issue as you? – l0ckm4 Jul 19 '22 at 08:39
  • 1
    @l0ckm4 yes I think so, but it was so long time ago, the solution is no longer valid I think. To acquire ticket code for console can be now done via API call in VMWare. I used a really horrid way to get it on older VMware versions. :D this is the function I maed for it: https://pastebin.com/EXAhLP38 for new version of vmware I use this function https://pastebin.com/e9zwNRUB – VladoPortos Jul 19 '22 at 12:29
  • @VladoPortos - nice one - thank you for taking the time to post your code for me as well. – l0ckm4 Jul 20 '22 at 14:00

3 Answers3

1

my best guess is that VCenter blocks requests with no user-agent header, and curl-cli adds such a header automatically, but libcurl / php's libcurl wrappers does not. try

curl_setopt($ch,CURLOPT_USERAGENT, 'php/' . PHP_VERSION . ' libcurl/' . (curl_version()['version']));

then you'll get something like

User-Agent: php/7.1.16 libcurl/7.59.0

which is truthful :)

hanshenrik
  • 19,904
  • 4
  • 43
  • 89
  • Thanks hanshenrik. I've added that and it does show User-Agent: php/7.2.14 libcurl/7.29.0 in the header now, but still not getting a good response. Pasting curl_dump in case that helps: https://pastebin.com/x2ZFSasp – SuperDogStar Jan 17 '19 at 12:30
  • @SuperDogStar hmm... and what headers do you get if you add `--verbose` to the curl command? – hanshenrik Jan 17 '19 at 12:46
  • Could the problem be something to do with the "Content-Length: -1" in the header? There's also an extra line that I am not sure where it's coming from. Curl_dump pasted here from PHP code: https://pastebin.com/x2ZFSasp – SuperDogStar Jan 17 '19 at 13:35
  • Okay, running with verbose. I also had to add --insecure to command line at the end to bypass SSL checking, forgot to add that above. Results with --verbose on curl command line can be found here: pastebin.com/pswSYk3b – SuperDogStar Jan 17 '19 at 14:14
1

The http 400 error is caused by this header:

curl_setopt($ch, CURLOPT_POST, true);

And replacing it with this one solves the issue:

curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
Arie Rave
  • 11
  • 1
-1

With curl you can connect in this way:

curl -X POST \
  https://<your_vcenter>/rest/com/vmware/cis/session \
  -H 'Accept: application/json' \
  -H 'Authorization: Basic <encoded_password...see *1)' \
  -H 'Content-Type: application/json' \
  -H 'vmware-use-header-authn: SomerandomValue'

*1 => https://en.wikipedia.org/wiki/Basic_access_authentication**

Then you get as response:

{
    "value": "vmware-api-session-id"
}

With this id you can do:

curl -X GET \
  https://<your_vcenter>/rest/vcenter/host \
  -H 'Accept: application/json' \
  -H 'Content-Type: application/json' \
  -H 'vmware-api-session-id: vmware-api-session-id' \
  -d '{
    "filter": {
    }
}'

and get

{
    "value": [
        {
            "host": "host-1",
            "name": "esx01.your.domain",
            "connection_state": "CONNECTED",
            "power_state": "POWERED_ON"
        },
        {
            "host": "host-2",
            "name": "esx02.your.domain",
            "connection_state": "CONNECTED",
            "power_state": "POWERED_ON"
        }
    ]
}
kaiSzy
  • 1