diff options
Diffstat (limited to 'src/zabbix_server/vmware/vmware_rest.c')
-rw-r--r-- | src/zabbix_server/vmware/vmware_rest.c | 237 |
1 files changed, 172 insertions, 65 deletions
diff --git a/src/zabbix_server/vmware/vmware_rest.c b/src/zabbix_server/vmware/vmware_rest.c index edb75b15364..78245603fda 100644 --- a/src/zabbix_server/vmware/vmware_rest.c +++ b/src/zabbix_server/vmware/vmware_rest.c @@ -32,7 +32,6 @@ typedef struct size_t alloc; size_t offset; char *url; - } ZBX_HTTPPAGE; @@ -239,6 +238,7 @@ static void vmware_entry_tags_init(zbx_vmware_data_t *data, zbx_vector_vmware_en * Purpose: cURL handle prepare * * * * Parameters: url - [IN] the vmware service url * + * is_new_api - [IN] flag to use new api version syntax * * easyhandle - [OUT] cURL handle * * page - [OUT] the response buffer for cURL * * headers - [OUT] the request headers for cURL * @@ -247,8 +247,8 @@ static void vmware_entry_tags_init(zbx_vmware_data_t *data, zbx_vector_vmware_en * Return value: SUCCEED if the cURL prepared, FAIL otherwise * * * ******************************************************************************/ -static int vmware_curl_init(const char *url, CURL **easyhandle, ZBX_HTTPPAGE *page, struct curl_slist **headers, - char **error) +static int vmware_curl_init(const char *url, unsigned char is_new_api, CURL **easyhandle, ZBX_HTTPPAGE *page, + struct curl_slist **headers, char **error) { # define INIT_PERF_REST_SIZE 2 * ZBX_KIBIBYTE # define ZBX_XML_HEADER1 "Accept: application/json, text/plain, */*" @@ -281,7 +281,14 @@ static int vmware_curl_init(const char *url, CURL **easyhandle, ZBX_HTTPPAGE *pa goto out; } - memcpy(&page->url[url_sz - ZBX_CONST_STRLEN("api")], "api", ZBX_CONST_STRLEN("api")); + if (0 == is_new_api) + { + page->url = zbx_dsprintf(page->url, "%.*s%s", (int)(url_sz - ZBX_CONST_STRLEN("sdk")), page->url, + "rest/com/vmware"); + } + else + memcpy(&page->url[url_sz - ZBX_CONST_STRLEN("api")], "api", ZBX_CONST_STRLEN("api")); + *headers = curl_slist_append(*headers, ZBX_XML_HEADER1); *headers = curl_slist_append(*headers, ZBX_XML_HEADER2); @@ -368,6 +375,28 @@ static int vmware_rest_response_open(const char *data, struct zbx_json_parse *jp return FAIL; } + if (SUCCEED == zbx_json_value_by_name(jp, "majorErrorCode", err, sizeof(err), NULL)) + { + char err_msg[VMWARE_SHORT_STR_LEN]; + const char *p = NULL; + struct zbx_json_parse jp_row; + + zbx_json_value_by_name(jp, "name", err, sizeof(err), NULL); + + if (SUCCEED != zbx_json_brackets_by_name(jp, "localizableMessages", &jp_data) || + NULL == (p = zbx_json_next(&jp_data, p)) || + SUCCEED != zbx_json_brackets_open(p, &jp_row) || + SUCCEED != zbx_json_value_by_name(&jp_row, "defaultMessage", err_msg, sizeof(err_msg), + NULL)) + { + err_msg[0] = '\0'; + } + + *error = zbx_dsprintf(*error, "%s:%s", err, err_msg); + + return FAIL; + } + return SUCCEED; } @@ -376,6 +405,7 @@ static int vmware_rest_response_open(const char *data, struct zbx_json_parse *jp * Purpose: authenticate rest service * * * * Parameters: service - [IN] the vmware service * + * is_new_api - [IN] flag to use new api version syntax * * easyhandle - [IN/OUT] cURL handle * * headers - [IN/OUT] the request headers for cURL * * page - [IN/OUT] the response buffer for cURL * @@ -384,8 +414,8 @@ static int vmware_rest_response_open(const char *data, struct zbx_json_parse *jp * Return value: SUCCEED if the rest authenticated, FAIL otherwise * * * ******************************************************************************/ -static int vmware_service_rest_authenticate(const zbx_vmware_service_t *service, CURL *easyhandle, - struct curl_slist **headers, ZBX_HTTPPAGE *page, char **error) +static int vmware_service_rest_authenticate(const zbx_vmware_service_t *service, unsigned char is_new_api, + CURL *easyhandle, struct curl_slist **headers, ZBX_HTTPPAGE *page, char **error) { int ret = FAIL; char tmp[MAX_STRING_LEN]; @@ -394,7 +424,7 @@ static int vmware_service_rest_authenticate(const zbx_vmware_service_t *service, zabbix_log(LOG_LEVEL_DEBUG, "In %s() '%s'@'%s'", __func__, service->username, service->url); - zbx_snprintf(tmp, sizeof(tmp),"%s/session", page->url); + zbx_snprintf(tmp, sizeof(tmp), 0 != is_new_api ? "%s/session" : "%s/cis/session", page->url); if (CURLE_OK != (err = curl_easy_setopt(easyhandle, opt = CURLOPT_POST, 1L)) || CURLE_OK != (err = curl_easy_setopt(easyhandle, opt = CURLOPT_URL, tmp)) || @@ -418,15 +448,39 @@ static int vmware_service_rest_authenticate(const zbx_vmware_service_t *service, *error = zbx_strdup(*error, "Cannot authenticate, received empty response."); goto out; } - else if ('"' != page->data[0] && FAIL == vmware_rest_response_open(page->data, NULL, error)) + + if (0 == is_new_api) { - *error = zbx_dsprintf(*error, "Cannot authenticate, %s.", *error); - goto out; + char token[MAX_STRING_LEN]; + struct zbx_json_parse jp; + + if (FAIL == vmware_rest_response_open(page->data, &jp, error)) + { + *error = zbx_dsprintf(*error, "Cannot authenticate: %s.", *error); + goto out; + } + + if (SUCCEED != zbx_json_value_by_name(&jp, "value", token, sizeof(token), NULL)) + { + *error = zbx_dsprintf(*error, "Cannot authenticate, cannot read vmware response: %s.", + zbx_json_strerror()); + goto out; + } + + zbx_snprintf(tmp, sizeof(tmp),"vmware-api-session-id: %s", token); + } + else + { + if ('"' != page->data[0] && FAIL == vmware_rest_response_open(page->data, NULL, error)) + { + *error = zbx_dsprintf(*error, "Authentication fail, %s.", *error); + goto out; + } + + zbx_lrtrim(page->data, "\""); + zbx_snprintf(tmp, sizeof(tmp),"vmware-api-session-id: %s", page->data); } - zbx_ltrim(page->data, "\""); - zbx_rtrim(page->data, "\""); - zbx_snprintf(tmp, sizeof(tmp),"vmware-api-session-id: %s", page->data); *headers = curl_slist_append(*headers, tmp); if (CURLE_OK != (err = curl_easy_setopt(easyhandle, opt = CURLOPT_HTTPHEADER, *headers))) @@ -456,6 +510,7 @@ static void vmware_service_rest_logout(CURL *easyhandle, ZBX_HTTPPAGE *page) zbx_snprintf(tmp, sizeof(tmp),"%s/session", page->url); if (CURLE_OK != (err = curl_easy_setopt(easyhandle, opt = CURLOPT_URL, tmp)) || + CURLE_OK != (err = curl_easy_setopt(easyhandle, opt = CURLOPT_POST, 0L)) || CURLE_OK != (err = curl_easy_setopt(easyhandle, opt = CURLOPT_CUSTOMREQUEST, "DELETE"))) { zabbix_log(LOG_LEVEL_DEBUG, "%s() cannot set cURL option %d: %s.", @@ -582,7 +637,17 @@ static int vmware_rest_post(const char *fn_parent, CURL *easyhandle, const char return FAIL; } - return vmware_http_request(fn_parent, easyhandle, url_suffix, jp, error); + if (SUCCEED != vmware_http_request(fn_parent, easyhandle, url_suffix, jp, error)) + return FAIL; + + if (CURLE_OK != (err = curl_easy_setopt(easyhandle, CURLOPT_POSTFIELDS, NULL))) + { + *error = zbx_dsprintf(*error, "Cannot set cURL option %d: %s.", CURLOPT_POSTFIELDS, + curl_easy_strerror(err)); + return FAIL; + } + + return SUCCEED; } /****************************************************************************** @@ -591,31 +656,46 @@ static int vmware_rest_post(const char *fn_parent, CURL *easyhandle, const char * * * Parameters: obj_id - [IN] the parent function name for Log records * * easyhandle - [IN] the CURL handle * + * is_new_api - [IN] flag to use new api version syntax * * ids - [OUT] the vector with tags id * * error - [OUT] the error message in the case of failure * * * * Return value: SUCCEED if the receive list of tags id, FAIL otherwise * * * ******************************************************************************/ -static int vmware_tags_linked_id(const zbx_vmware_obj_id_t *obj_id, CURL *easyhandle, zbx_vector_str_t *ids, - char **error) +static int vmware_tags_linked_id(const zbx_vmware_obj_id_t *obj_id, CURL *easyhandle, unsigned char is_new_api, + zbx_vector_str_t *ids, char **error) { - int ret = FAIL; + int ret; char tmp[MAX_STRING_LEN]; - const char *p = NULL; + const char *url, *p = NULL; struct zbx_json_parse jp; zabbix_log(LOG_LEVEL_DEBUG, "In %s() obj_id:%s", __func__, obj_id->id); zbx_snprintf(tmp, sizeof(tmp),"{\"object_id\":{\"id\":\"%s\",\"type\":\"%s\"}}", obj_id->id, obj_id->type); - if (SUCCEED == (ret = vmware_rest_post(__func__, easyhandle, - "/cis/tagging/tag-association?action=list-attached-tags", tmp, &jp, error))) + if (0 != is_new_api) + url = "/cis/tagging/tag-association?action=list-attached-tags"; + else + url = "/cis/tagging/tag-association?~action=list-attached-tags"; + + if (SUCCEED == (ret = vmware_rest_post(__func__, easyhandle, url, tmp, &jp, error))) { - while (NULL != (p = zbx_json_next_value(&jp, p, tmp, sizeof(tmp), NULL))) + struct zbx_json_parse jp_step; + + if (0 == is_new_api) + { + if (SUCCEED != (ret = zbx_json_brackets_by_name(&jp, "value", &jp_step))) + goto out; + } + else + jp_step = jp; + + while (NULL != (p = zbx_json_next_value(&jp_step, p, tmp, sizeof(tmp), NULL))) zbx_vector_str_append(ids, zbx_strdup(NULL, tmp)); } - +out: zabbix_log(LOG_LEVEL_DEBUG, "End of %s() ids:%d", __func__, ids->values_num); return ret; @@ -627,6 +707,7 @@ static int vmware_tags_linked_id(const zbx_vmware_obj_id_t *obj_id, CURL *easyha * * * Parameters: tag_id - [IN] the tag id * * easyhandle - [IN] the CURL handle * + * is_new_api - [IN] flag to use new api version syntax * * tags - [OUT] the vector with tags info * * categories - [OUT] the vector with categories info * * error - [OUT] the error message in the case of failure * @@ -634,36 +715,45 @@ static int vmware_tags_linked_id(const zbx_vmware_obj_id_t *obj_id, CURL *easyha * Return value: SUCCEED if the receive tag details, FAIL otherwise * * * ******************************************************************************/ -static int vmware_vectors_update(const char *tag_id, CURL *easyhandle, zbx_vector_vmware_tag_t *tags, - zbx_vector_vmware_key_value_t *categories, char **error) +static int vmware_vectors_update(const char *tag_id, CURL *easyhandle, unsigned char is_new_api, + zbx_vector_vmware_tag_t *tags, zbx_vector_vmware_key_value_t *categories, char **error) { - struct zbx_json_parse jp; + struct zbx_json_parse jp, jp_data; int i; char cid[VMWARE_SHORT_STR_LEN], name[MAX_STRING_LEN], desc[MAX_STRING_LEN]; + const char *url_tag, *url_cat; zbx_vmware_key_value_t cat_cmp; zbx_vmware_tag_t *tag; zabbix_log(LOG_LEVEL_DEBUG, "%s() tag_id:%s", __func__, tag_id); - if (FAIL == vmware_rest_get(__func__, easyhandle, "/cis/tagging/tag/", tag_id, &jp, error)) - return FAIL; - - if (FAIL == zbx_json_value_by_name(&jp, "name", name, sizeof(name), NULL)) + if (0 == is_new_api) { - *error = zbx_dsprintf(*error, "Cannot read vmware response: %s", zbx_json_strerror()); - return FAIL; + url_tag = "/cis/tagging/tag/id:"; + url_cat = "/cis/tagging/category/id:"; } - - if (FAIL == zbx_json_value_by_name(&jp, "description", desc, sizeof(desc), NULL)) + else { - *error = zbx_dsprintf(*error, "Cannot read vmware response: %s", zbx_json_strerror()); + url_tag = "/cis/tagging/tag/"; + url_cat = "/cis/tagging/category/"; + } + + if (FAIL == vmware_rest_get(__func__, easyhandle, url_tag, tag_id, &jp_data, error)) return FAIL; + + if (0 == is_new_api) + { + if (SUCCEED != zbx_json_brackets_by_name(&jp_data, "value", &jp)) + goto json_err; } + else + jp = jp_data; - if (FAIL == zbx_json_value_by_name(&jp, "category_id", cid, sizeof(cid), NULL)) + if (FAIL == zbx_json_value_by_name(&jp, "name", name, sizeof(name), NULL) || + FAIL == zbx_json_value_by_name(&jp, "description", desc, sizeof(desc), NULL) || + FAIL == zbx_json_value_by_name(&jp, "category_id", cid, sizeof(cid), NULL)) { - *error = zbx_dsprintf(*error, "Cannot read vmware response: %s", zbx_json_strerror()); - return FAIL; + goto json_err; } cat_cmp.key = cid; @@ -673,14 +763,19 @@ static int vmware_vectors_update(const char *tag_id, CURL *easyhandle, zbx_vecto zbx_vmware_key_value_t category; char value[MAX_STRING_LEN]; - if (FAIL == vmware_rest_get(__func__, easyhandle, "/cis/tagging/category/", cid, &jp, error)) + if (FAIL == vmware_rest_get(__func__, easyhandle, url_cat, cid, &jp_data, error)) return FAIL; - if (FAIL == zbx_json_value_by_name(&jp, "name", value, sizeof(value), NULL)) + if (0 == is_new_api) { - *error = zbx_dsprintf(*error, "Cannot read vmware response: %s", zbx_json_strerror()); - return FAIL; + if (SUCCEED != zbx_json_brackets_by_name(&jp_data, "value", &jp)) + goto json_err; } + else + jp = jp_data; + + if (FAIL == zbx_json_value_by_name(&jp, "name", value, sizeof(value), NULL)) + goto json_err; category.key = zbx_strdup(NULL, cid); category.value = zbx_strdup(NULL, value); @@ -713,13 +808,17 @@ static int vmware_vectors_update(const char *tag_id, CURL *easyhandle, zbx_vecto tags->values[i]->name, tags->values[i]->description, tags->values[i]->category); return i; +json_err: + *error = zbx_dsprintf(*error, "Cannot read vmware response: %s", zbx_json_strerror()); + return FAIL; } /****************************************************************************** * * * Purpose: create vector with tags details * * * - * Parameters: entity_tags - [IN/OUT] the tag entity * + * Parameters: is_new_api - [IN] flag to use new api version syntax * + * entity_tags - [IN/OUT] the tag entity * * tags - [IN/OUT] the vector with tags info * * categories - [IN/OUT] the vector with categories info * * easyhandle - [IN/OUT] the CURL handle * @@ -727,8 +826,8 @@ static int vmware_vectors_update(const char *tag_id, CURL *easyhandle, zbx_vecto * Return value: SUCCEED if the create tags vector, FAIL otherwise * * * ******************************************************************************/ -static int vmware_tags_get(zbx_vmware_entity_tags_t *entity_tags, zbx_vector_vmware_tag_t *tags, - zbx_vector_vmware_key_value_t *categories, CURL *easyhandle) +static int vmware_tags_get(unsigned char is_new_api, zbx_vmware_entity_tags_t *entity_tags, + zbx_vector_vmware_tag_t *tags, zbx_vector_vmware_key_value_t *categories, CURL *easyhandle) { int i, found_tags = 0; zbx_vector_str_t tag_ids; @@ -737,7 +836,7 @@ static int vmware_tags_get(zbx_vmware_entity_tags_t *entity_tags, zbx_vector_vmw zbx_vector_str_create(&tag_ids); - if (FAIL == vmware_tags_linked_id(entity_tags->obj_id, easyhandle, &tag_ids, &entity_tags->error)) + if (FAIL == vmware_tags_linked_id(entity_tags->obj_id, easyhandle, is_new_api, &tag_ids, &entity_tags->error)) goto out; for (i = 0; i < tag_ids.values_num; i++) @@ -746,8 +845,8 @@ static int vmware_tags_get(zbx_vmware_entity_tags_t *entity_tags, zbx_vector_vmw zbx_vmware_tag_t *tag, cmp = {.id = tag_ids.values[i]}; if (FAIL == (j = zbx_vector_vmware_tag_bsearch(tags, &cmp, zbx_vmware_tag_id_compare)) && - FAIL == (j = vmware_vectors_update(tag_ids.values[i], easyhandle, tags, categories, - &entity_tags->error))) + FAIL == (j = vmware_vectors_update(tag_ids.values[i], easyhandle, is_new_api, tags, + categories, &entity_tags->error))) { zabbix_log(LOG_LEVEL_DEBUG, "%s() problem with tag_id:%s error:%s", __func__, tag_ids.values[i], entity_tags->error); @@ -781,42 +880,49 @@ out: ******************************************************************************/ int zbx_vmware_service_update_tags(zbx_vmware_service_t *service) { - int i, found_tags = 0, ret = FAIL; + int i, version, found_tags = 0, ret = FAIL; + char *error = NULL; + unsigned char is_new_api; zbx_vector_vmware_entity_tags_t entity_tags; - zbx_vector_vmware_tag_t tags; + zbx_vector_vmware_tag_t tags; zbx_vector_vmware_key_value_t categories; CURL *easyhandle = NULL; struct curl_slist *headers = NULL; ZBX_HTTPPAGE page = {.data = NULL, .url = NULL}; - char *error = NULL; - zabbix_log(LOG_LEVEL_DEBUG, "In %s() vc version:%s", __func__, service->version); + zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __func__); + + zbx_vector_vmware_entity_tags_create(&entity_tags); - if (702 > service->major_version * 100 + service->minor_version * 10 + service->patch_version) + zbx_vmware_lock(); + version = service->major_version * 100 + service->minor_version * 10 + service->update_version; + + if (650 > version) { - error = zbx_strdup(error, "Tags are supported since vmware version 7.0.2"); + zbx_vmware_unlock(); + error = zbx_strdup(error, "Tags are supported since vmware version 6.5."); goto out; } - zbx_vector_vmware_tag_create(&tags); - zbx_vector_vmware_key_value_create(&categories); - zbx_vector_vmware_entity_tags_create(&entity_tags); - - zbx_vmware_lock(); vmware_entry_tags_init(service->data, &entity_tags); zbx_vmware_unlock(); + zabbix_log(LOG_LEVEL_DEBUG, "%s() vc version:%d", __func__, version); + + zbx_vector_vmware_tag_create(&tags); + zbx_vector_vmware_key_value_create(&categories); + is_new_api = (702 <= version) ? 1 : 0; + if (0 != entity_tags.values_num && ( - SUCCEED != vmware_curl_init(service->url, &easyhandle, &page, &headers, &error) || - SUCCEED != vmware_service_rest_authenticate(service, easyhandle, &headers, &page, &error))) + SUCCEED != vmware_curl_init(service->url, is_new_api, &easyhandle, &page, &headers, &error) || + SUCCEED != vmware_service_rest_authenticate(service, is_new_api, easyhandle, &headers, &page, + &error))) { goto clean; } for (i = 0; i < entity_tags.values_num; i++) - { - found_tags += vmware_tags_get(entity_tags.values[i], &tags, &categories, easyhandle); - } + found_tags += vmware_tags_get(is_new_api, entity_tags.values[i], &tags, &categories, easyhandle); if (NULL != headers) vmware_service_rest_logout(easyhandle, &page); @@ -827,15 +933,16 @@ int zbx_vmware_service_update_tags(zbx_vmware_service_t *service) clean: zbx_vector_vmware_tag_clear_ext(&tags, vmware_tag_free); zbx_vector_vmware_key_value_clear_ext(&categories, vmware_key_value_free); - zbx_vector_vmware_entity_tags_clear_ext(&entity_tags, vmware_entity_tags_free); zbx_vector_vmware_tag_destroy(&tags); zbx_vector_vmware_key_value_destroy(&categories); - zbx_vector_vmware_entity_tags_destroy(&entity_tags); curl_slist_free_all(headers); curl_easy_cleanup(easyhandle); zbx_free(page.data); zbx_free(page.url); out: + zbx_vector_vmware_entity_tags_clear_ext(&entity_tags, vmware_entity_tags_free); + zbx_vector_vmware_entity_tags_destroy(&entity_tags); + if (FAIL == ret) { zbx_vmware_shared_tags_error_set(error, &service->data_tags); |