We are writing a C++ program to integrate to VMware vCenter. We are using the rest API The connection was failing with not found so we have created a separate test program.
We have added a lot of logging and the session seems to be connecting but not accepting the credentials.
bool generateSessionID(std::string &sessionID) {
CURL *curl;
CURLcode res = CURLE_OK;
std::string response;
std::string hostname = "192.168.0.223"; // Hardcoded vCenter IP address
std::string username = "[email protected]"; // Hardcoded username
std::string password = "Password1"; // Hardcoded password
curl = curl_easy_init();
if (curl) {
std::string url = "https://" + hostname + "/rest/com/vmware/cis/session";
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
curl_easy_setopt(curl, CURLOPT_USERNAME, username.c_str());
curl_easy_setopt(curl, CURLOPT_PASSWORD, password.c_str());
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
struct curl_slist *headers = NULL;
headers = curl_slist_append(headers, "Content-Type: application/json");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
res = curl_easy_perform(curl);
if (res != CURLE_OK) {
fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res));
} else {
long http_code = 0;
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_code);
std::cout << "HTTP response code: " << http_code << std::endl;
std::cout << "Response: " << response << std::endl;
if (http_code == 200) {
Json::CharReaderBuilder builder;
Json::CharReader *reader = builder.newCharReader();
Json::Value jsonObj;
std::string errs;
if (reader->parse(response.c_str(), response.c_str() + response.size(), &jsonObj, &errs)) {
sessionID = jsonObj["value"].asString();
std::cout << "Session ID: " << sessionID << std::endl;
} else {
std::cerr << "Failed to parse JSON: " << errs << std::endl;
}
delete reader;
} else {
std::cerr << "Error: HTTP response code " << http_code << std::endl;
}
}
curl_slist_free_all(headers);
curl_easy_cleanup(curl);
}
return res == CURLE_OK;
}
This is the error message we get
HTTP response code: 404
Response: {"majorErrorCode":404,"name":"com.vmware.vapi.rest.httpNotFound","localizableMessages":[{"args": [],"defaultMessage":"Not found.","id":"com.vmware.vapi.rest.httpNotFound"}],"type":"com.vmware.vapi.std.errors.not_found","value":{"messages":[{"args":[],"default_message":"Not found.","id":"com.vmware.vapi.rest.httpNotFound"}]}}
Error: HTTP response code 404
We are using the same endpoint in the C++ code as we are when testing from the command line but getting a not found error.
We have tested the connectivity successfully from the command line using the following
http --verify=no -a '[email protected]:Password1' POST https://192.168.0.223/rest/com/vmware/cis/session
HTTP/1.1 200 OK
content-type: application/json
date: Fri, 14 Jun 2024 13:20:32 GMT
expires: Thu, 01 Jan 1970 00:00:00 GMT
set-cookie: vmware-api-session-id=3e507a19d9653a97a6b520e9020a9aee; Path=/rest; Secure; HttpOnly, vmware-api-session-id=3e507a19d9653a97a6b520e9020a9aee; Path=/api; Secure; HttpOnly
transfer-encoding: chunked
x-envoy-upstream-service-time: 195
{
"value": "3e507a19d9653a97a6b520e9020a9aee"
}
Using curl
curl -k -u '[email protected]:Password1' -X POST https://192.168.0.223/rest/com/vmware/cis/session
{"value":"0f9b655ee47584b4493c27c38a99fa55"}
The only difference I can see - libcurl performs GET request, other attempts perform POST requests.
You might want to add
curl_easy_setopt(curl, CURLOPT_POST, 1L);
You can convert the successful curl command example into a C code
curl --libcurl example.c -k -u '[email protected]:Password1' -X POST https://192.168.0.223/rest/com/vmware/cis/session