From ac041072f8f37835c9c8891131ec5b085b353db7 Mon Sep 17 00:00:00 2001 From: Matthias Bolte Date: Fri, 30 Jul 2010 22:08:35 +0200 Subject: [PATCH] esx: Parse the path of the URI The path will be used to specify the datacenter, compute resource and host system to be used with a vpx:// connection. --- src/esx/esx_driver.c | 49 +++++++++----------- src/esx/esx_util.c | 104 +++++++++++++++++++++++++++---------------- src/esx/esx_util.h | 11 +++-- src/esx/esx_vi.c | 14 +++--- src/esx/esx_vi.h | 3 +- 5 files changed, 102 insertions(+), 79 deletions(-) diff --git a/src/esx/esx_driver.c b/src/esx/esx_driver.c index 913420c42b..3bdc55197e 100644 --- a/src/esx/esx_driver.c +++ b/src/esx/esx_driver.c @@ -294,7 +294,7 @@ static int esxConnectToHost(esxPrivate *priv, virConnectAuthPtr auth, const char *hostname, int port, const char *predefinedUsername, - esxUtil_ParsedQuery *parsedQuery, + esxUtil_ParsedUri *parsedUri, esxVI_ProductVersion expectedProductVersion, char **vCenterIpAddress) { @@ -347,7 +347,7 @@ esxConnectToHost(esxPrivate *priv, virConnectAuthPtr auth, if (esxVI_Context_Alloc(&priv->host) < 0 || esxVI_Context_Connect(priv->host, url, ipAddress, username, password, - parsedQuery) < 0) { + parsedUri) < 0) { goto cleanup; } @@ -416,7 +416,7 @@ static int esxConnectToVCenter(esxPrivate *priv, virConnectAuthPtr auth, const char *hostname, int port, const char *predefinedUsername, - esxUtil_ParsedQuery *parsedQuery) + esxUtil_ParsedUri *parsedUri) { int result = -1; char ipAddress[NI_MAXHOST] = ""; @@ -459,7 +459,7 @@ esxConnectToVCenter(esxPrivate *priv, virConnectAuthPtr auth, if (esxVI_Context_Alloc(&priv->vCenter) < 0 || esxVI_Context_Connect(priv->vCenter, url, ipAddress, username, - password, parsedQuery) < 0) { + password, parsedUri) < 0) { goto cleanup; } @@ -528,7 +528,7 @@ esxOpen(virConnectPtr conn, virConnectAuthPtr auth, int flags ATTRIBUTE_UNUSED) { virDrvOpenStatus result = VIR_DRV_OPEN_ERROR; esxPrivate *priv = NULL; - esxUtil_ParsedQuery *parsedQuery = NULL; + esxUtil_ParsedUri *parsedUri = NULL; char *potentialVCenterIpAddress = NULL; char vCenterIpAddress[NI_MAXHOST] = ""; @@ -545,29 +545,24 @@ esxOpen(virConnectPtr conn, virConnectAuthPtr auth, int flags ATTRIBUTE_UNUSED) return VIR_DRV_OPEN_DECLINED; } - if (conn->uri->path != NULL && STRNEQ(conn->uri->path, "") && - STRNEQ(conn->uri->path, "/")) { - VIR_WARN("Ignoring unexpected path '%s' in URI", conn->uri->path); - } - /* Allocate per-connection private data */ if (VIR_ALLOC(priv) < 0) { virReportOOMError(); goto cleanup; } - if (esxUtil_ParseQuery(&parsedQuery, conn->uri) < 0) { + if (esxUtil_ParseUri(&parsedUri, conn->uri) < 0) { goto cleanup; } - priv->transport = parsedQuery->transport; - parsedQuery->transport = NULL; + priv->transport = parsedUri->transport; + parsedUri->transport = NULL; priv->maxVcpus = -1; priv->supportsVMotion = esxVI_Boolean_Undefined; priv->supportsLongMode = esxVI_Boolean_Undefined; - priv->autoAnswer = parsedQuery->autoAnswer ? esxVI_Boolean_True - : esxVI_Boolean_False; + priv->autoAnswer = parsedUri->autoAnswer ? esxVI_Boolean_True + : esxVI_Boolean_False; priv->usedCpuTimeCounterId = -1; /* @@ -597,7 +592,7 @@ esxOpen(virConnectPtr conn, virConnectAuthPtr auth, int flags ATTRIBUTE_UNUSED) STRCASEEQ(conn->uri->scheme, "gsx")) { /* Connect to host */ if (esxConnectToHost(priv, auth, conn->uri->server, conn->uri->port, - conn->uri->user, parsedQuery, + conn->uri->user, parsedUri, STRCASEEQ(conn->uri->scheme, "esx") ? esxVI_ProductVersion_ESX : esxVI_ProductVersion_GSX, @@ -606,8 +601,8 @@ esxOpen(virConnectPtr conn, virConnectAuthPtr auth, int flags ATTRIBUTE_UNUSED) } /* Connect to vCenter */ - if (parsedQuery->vCenter != NULL) { - if (STREQ(parsedQuery->vCenter, "*")) { + if (parsedUri->vCenter != NULL) { + if (STREQ(parsedUri->vCenter, "*")) { if (potentialVCenterIpAddress == NULL) { ESX_ERROR(VIR_ERR_INTERNAL_ERROR, "%s", _("This host is not managed by a vCenter")); @@ -622,7 +617,7 @@ esxOpen(virConnectPtr conn, virConnectAuthPtr auth, int flags ATTRIBUTE_UNUSED) goto cleanup; } } else { - if (esxUtil_ResolveHostname(parsedQuery->vCenter, + if (esxUtil_ResolveHostname(parsedUri->vCenter, vCenterIpAddress, NI_MAXHOST) < 0) { goto cleanup; } @@ -633,14 +628,14 @@ esxOpen(virConnectPtr conn, virConnectAuthPtr auth, int flags ATTRIBUTE_UNUSED) _("This host is managed by a vCenter with IP " "address %s, but a mismachting vCenter '%s' " "(%s) has been specified"), - potentialVCenterIpAddress, parsedQuery->vCenter, + potentialVCenterIpAddress, parsedUri->vCenter, vCenterIpAddress); goto cleanup; } } if (esxConnectToVCenter(priv, auth, vCenterIpAddress, - conn->uri->port, NULL, parsedQuery) < 0) { + conn->uri->port, NULL, parsedUri) < 0) { goto cleanup; } } @@ -649,7 +644,7 @@ esxOpen(virConnectPtr conn, virConnectAuthPtr auth, int flags ATTRIBUTE_UNUSED) } else { /* VPX */ /* Connect to vCenter */ if (esxConnectToVCenter(priv, auth, conn->uri->server, conn->uri->port, - conn->uri->user, parsedQuery) < 0) { + conn->uri->user, parsedUri) < 0) { goto cleanup; } @@ -678,7 +673,7 @@ esxOpen(virConnectPtr conn, virConnectAuthPtr auth, int flags ATTRIBUTE_UNUSED) VIR_FREE(priv); } - esxUtil_FreeParsedQuery(&parsedQuery); + esxUtil_FreeParsedUri(&parsedUri); VIR_FREE(potentialVCenterIpAddress); return result; @@ -3113,14 +3108,14 @@ esxDomainMigratePrepare(virConnectPtr dconn, unsigned long resource ATTRIBUTE_UNUSED) { int result = -1; - esxUtil_ParsedQuery *parsedQuery = NULL; + esxUtil_ParsedUri *parsedUri = NULL; if (uri_in == NULL) { - if (esxUtil_ParseQuery(&parsedQuery, dconn->uri) < 0) { + if (esxUtil_ParseUri(&parsedUri, dconn->uri) < 0) { return -1; } - if (virAsprintf(uri_out, "%s://%s:%d/sdk", parsedQuery->transport, + if (virAsprintf(uri_out, "%s://%s:%d/sdk", parsedUri->transport, dconn->uri->server, dconn->uri->port) < 0) { virReportOOMError(); goto cleanup; @@ -3130,7 +3125,7 @@ esxDomainMigratePrepare(virConnectPtr dconn, result = 0; cleanup: - esxUtil_FreeParsedQuery(&parsedQuery); + esxUtil_FreeParsedUri(&parsedUri); return result; } diff --git a/src/esx/esx_util.c b/src/esx/esx_util.c index d79de2ce75..75a9aaf26d 100644 --- a/src/esx/esx_util.c +++ b/src/esx/esx_util.c @@ -41,7 +41,7 @@ int -esxUtil_ParseQuery(esxUtil_ParsedQuery **parsedQuery, xmlURIPtr uri) +esxUtil_ParseUri(esxUtil_ParsedUri **parsedUri, xmlURIPtr uri) { int result = -1; struct qparam_set *queryParamSet = NULL; @@ -50,13 +50,14 @@ esxUtil_ParseQuery(esxUtil_ParsedQuery **parsedQuery, xmlURIPtr uri) int noVerify; int autoAnswer; char *tmp; + char *saveptr; - if (parsedQuery == NULL || *parsedQuery != NULL) { + if (parsedUri == NULL || *parsedUri != NULL) { ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR, "%s", _("Invalid argument")); return -1; } - if (VIR_ALLOC(*parsedQuery) < 0) { + if (VIR_ALLOC(*parsedUri) < 0) { virReportOOMError(); return -1; } @@ -75,29 +76,29 @@ esxUtil_ParseQuery(esxUtil_ParsedQuery **parsedQuery, xmlURIPtr uri) queryParam = &queryParamSet->p[i]; if (STRCASEEQ(queryParam->name, "transport")) { - VIR_FREE((*parsedQuery)->transport); + VIR_FREE((*parsedUri)->transport); - (*parsedQuery)->transport = strdup(queryParam->value); + (*parsedUri)->transport = strdup(queryParam->value); - if ((*parsedQuery)->transport == NULL) { + if ((*parsedUri)->transport == NULL) { virReportOOMError(); goto cleanup; } - if (STRNEQ((*parsedQuery)->transport, "http") && - STRNEQ((*parsedQuery)->transport, "https")) { + if (STRNEQ((*parsedUri)->transport, "http") && + STRNEQ((*parsedUri)->transport, "https")) { ESX_ERROR(VIR_ERR_INVALID_ARG, _("Query parameter 'transport' has unexpected value " "'%s' (should be http|https)"), - (*parsedQuery)->transport); + (*parsedUri)->transport); goto cleanup; } } else if (STRCASEEQ(queryParam->name, "vcenter")) { - VIR_FREE((*parsedQuery)->vCenter); + VIR_FREE((*parsedUri)->vCenter); - (*parsedQuery)->vCenter = strdup(queryParam->value); + (*parsedUri)->vCenter = strdup(queryParam->value); - if ((*parsedQuery)->vCenter == NULL) { + if ((*parsedUri)->vCenter == NULL) { virReportOOMError(); goto cleanup; } @@ -110,7 +111,7 @@ esxUtil_ParseQuery(esxUtil_ParsedQuery **parsedQuery, xmlURIPtr uri) goto cleanup; } - (*parsedQuery)->noVerify = noVerify != 0; + (*parsedUri)->noVerify = noVerify != 0; } else if (STRCASEEQ(queryParam->name, "auto_answer")) { if (virStrToLong_i(queryParam->value, NULL, 10, &autoAnswer) < 0 || (autoAnswer != 0 && autoAnswer != 1)) { @@ -120,23 +121,23 @@ esxUtil_ParseQuery(esxUtil_ParsedQuery **parsedQuery, xmlURIPtr uri) goto cleanup; } - (*parsedQuery)->autoAnswer = autoAnswer != 0; + (*parsedUri)->autoAnswer = autoAnswer != 0; } else if (STRCASEEQ(queryParam->name, "proxy")) { /* Expected format: [://][:] */ - (*parsedQuery)->proxy = true; - (*parsedQuery)->proxy_type = CURLPROXY_HTTP; - VIR_FREE((*parsedQuery)->proxy_hostname); - (*parsedQuery)->proxy_port = 1080; + (*parsedUri)->proxy = true; + (*parsedUri)->proxy_type = CURLPROXY_HTTP; + VIR_FREE((*parsedUri)->proxy_hostname); + (*parsedUri)->proxy_port = 1080; if ((tmp = STRSKIP(queryParam->value, "http://")) != NULL) { - (*parsedQuery)->proxy_type = CURLPROXY_HTTP; + (*parsedUri)->proxy_type = CURLPROXY_HTTP; } else if ((tmp = STRSKIP(queryParam->value, "socks://")) != NULL || (tmp = STRSKIP(queryParam->value, "socks5://")) != NULL) { - (*parsedQuery)->proxy_type = CURLPROXY_SOCKS5; + (*parsedUri)->proxy_type = CURLPROXY_SOCKS5; } else if ((tmp = STRSKIP(queryParam->value, "socks4://")) != NULL) { - (*parsedQuery)->proxy_type = CURLPROXY_SOCKS4; + (*parsedUri)->proxy_type = CURLPROXY_SOCKS4; } else if ((tmp = STRSKIP(queryParam->value, "socks4a://")) != NULL) { - (*parsedQuery)->proxy_type = CURLPROXY_SOCKS4A; + (*parsedUri)->proxy_type = CURLPROXY_SOCKS4A; } else if ((tmp = strstr(queryParam->value, "://")) != NULL) { *tmp = '\0'; @@ -149,15 +150,15 @@ esxUtil_ParseQuery(esxUtil_ParsedQuery **parsedQuery, xmlURIPtr uri) tmp = queryParam->value; } - (*parsedQuery)->proxy_hostname = strdup(tmp); + (*parsedUri)->proxy_hostname = strdup(tmp); - if ((*parsedQuery)->proxy_hostname == NULL) { + if ((*parsedUri)->proxy_hostname == NULL) { virReportOOMError(); goto cleanup; } - if ((tmp = strchr((*parsedQuery)->proxy_hostname, ':')) != NULL) { - if (tmp == (*parsedQuery)->proxy_hostname) { + if ((tmp = strchr((*parsedUri)->proxy_hostname, ':')) != NULL) { + if (tmp == (*parsedUri)->proxy_hostname) { ESX_ERROR(VIR_ERR_INVALID_ARG, "%s", _("Query parameter 'proxy' doesn't contain a " "hostname")); @@ -167,9 +168,9 @@ esxUtil_ParseQuery(esxUtil_ParsedQuery **parsedQuery, xmlURIPtr uri) *tmp++ = '\0'; if (virStrToLong_i(tmp, NULL, 10, - &(*parsedQuery)->proxy_port) < 0 || - (*parsedQuery)->proxy_port < 1 || - (*parsedQuery)->proxy_port > 65535) { + &(*parsedUri)->proxy_port) < 0 || + (*parsedUri)->proxy_port < 1 || + (*parsedUri)->proxy_port > 65535) { ESX_ERROR(VIR_ERR_INVALID_ARG, _("Query parameter 'proxy' has unexpected port" "value '%s' (should be [1..65535])"), tmp); @@ -182,10 +183,32 @@ esxUtil_ParseQuery(esxUtil_ParsedQuery **parsedQuery, xmlURIPtr uri) } } - if ((*parsedQuery)->transport == NULL) { - (*parsedQuery)->transport = strdup("https"); + /* Expected format: [/]/[/] */ + if (uri->path != NULL) { + tmp = strdup(uri->path); - if ((*parsedQuery)->transport == NULL) { + if (tmp == NULL) { + virReportOOMError(); + goto cleanup; + } + + if (esxVI_String_DeepCopyValue(&(*parsedUri)->path_datacenter, + strtok_r(tmp, "/", &saveptr)) < 0 || + esxVI_String_DeepCopyValue(&(*parsedUri)->path_computeResource, + strtok_r(NULL, "/", &saveptr)) < 0 || + esxVI_String_DeepCopyValue(&(*parsedUri)->path_hostSystem, + strtok_r(NULL, "", &saveptr)) < 0) { + VIR_FREE(tmp); + goto cleanup; + } + + VIR_FREE(tmp); + } + + if ((*parsedUri)->transport == NULL) { + (*parsedUri)->transport = strdup("https"); + + if ((*parsedUri)->transport == NULL) { virReportOOMError(); goto cleanup; } @@ -195,7 +218,7 @@ esxUtil_ParseQuery(esxUtil_ParsedQuery **parsedQuery, xmlURIPtr uri) cleanup: if (result < 0) { - esxUtil_FreeParsedQuery(parsedQuery); + esxUtil_FreeParsedUri(parsedUri); } if (queryParamSet != NULL) { @@ -209,17 +232,20 @@ esxUtil_ParseQuery(esxUtil_ParsedQuery **parsedQuery, xmlURIPtr uri) void -esxUtil_FreeParsedQuery(esxUtil_ParsedQuery **parsedQuery) +esxUtil_FreeParsedUri(esxUtil_ParsedUri **parsedUri) { - if (parsedQuery == NULL || *parsedQuery == NULL) { + if (parsedUri == NULL || *parsedUri == NULL) { return; } - VIR_FREE((*parsedQuery)->transport); - VIR_FREE((*parsedQuery)->vCenter); - VIR_FREE((*parsedQuery)->proxy_hostname); + VIR_FREE((*parsedUri)->transport); + VIR_FREE((*parsedUri)->vCenter); + VIR_FREE((*parsedUri)->proxy_hostname); + VIR_FREE((*parsedUri)->path_datacenter); + VIR_FREE((*parsedUri)->path_computeResource); + VIR_FREE((*parsedUri)->path_hostSystem); - VIR_FREE(*parsedQuery); + VIR_FREE(*parsedUri); } diff --git a/src/esx/esx_util.h b/src/esx/esx_util.h index a1927a611e..99ce81d314 100644 --- a/src/esx/esx_util.h +++ b/src/esx/esx_util.h @@ -29,9 +29,9 @@ # include "internal.h" # include "conf.h" -typedef struct _esxUtil_ParsedQuery esxUtil_ParsedQuery; +typedef struct _esxUtil_ParsedUri esxUtil_ParsedUri; -struct _esxUtil_ParsedQuery { +struct _esxUtil_ParsedUri { char *transport; char *vCenter; bool noVerify; @@ -40,11 +40,14 @@ struct _esxUtil_ParsedQuery { int proxy_type; char *proxy_hostname; int proxy_port; + char *path_datacenter; + char *path_computeResource; + char *path_hostSystem; }; -int esxUtil_ParseQuery(esxUtil_ParsedQuery **parsedQuery, xmlURIPtr uri); +int esxUtil_ParseUri(esxUtil_ParsedUri **parsedUri, xmlURIPtr uri); -void esxUtil_FreeParsedQuery(esxUtil_ParsedQuery **parsedQuery); +void esxUtil_FreeParsedUri(esxUtil_ParsedUri **parsedUri); int esxUtil_ParseVirtualMachineIDString(const char *id_string, int *id); diff --git a/src/esx/esx_vi.c b/src/esx/esx_vi.c index 98b8bcd543..5695881c3b 100644 --- a/src/esx/esx_vi.c +++ b/src/esx/esx_vi.c @@ -277,7 +277,7 @@ esxVI_CURL_Perform(esxVI_Context *ctx, const char *url) int esxVI_Context_Connect(esxVI_Context *ctx, const char *url, const char *ipAddress, const char *username, - const char *password, esxUtil_ParsedQuery *parsedQuery) + const char *password, esxUtil_ParsedUri *parsedUri) { int result = -1; esxVI_String *propertyNameList = NULL; @@ -329,9 +329,9 @@ esxVI_Context_Connect(esxVI_Context *ctx, const char *url, curl_easy_setopt(ctx->curl_handle, CURLOPT_HEADER, 0); curl_easy_setopt(ctx->curl_handle, CURLOPT_FOLLOWLOCATION, 0); curl_easy_setopt(ctx->curl_handle, CURLOPT_SSL_VERIFYPEER, - parsedQuery->noVerify ? 0 : 1); + parsedUri->noVerify ? 0 : 1); curl_easy_setopt(ctx->curl_handle, CURLOPT_SSL_VERIFYHOST, - parsedQuery->noVerify ? 0 : 2); + parsedUri->noVerify ? 0 : 2); curl_easy_setopt(ctx->curl_handle, CURLOPT_COOKIEFILE, ""); curl_easy_setopt(ctx->curl_handle, CURLOPT_HTTPHEADER, ctx->curl_headers); curl_easy_setopt(ctx->curl_handle, CURLOPT_READFUNCTION, @@ -345,13 +345,13 @@ esxVI_Context_Connect(esxVI_Context *ctx, const char *url, curl_easy_setopt(ctx->curl_handle, CURLOPT_VERBOSE, 1); #endif - if (parsedQuery->proxy) { + if (parsedUri->proxy) { curl_easy_setopt(ctx->curl_handle, CURLOPT_PROXY, - parsedQuery->proxy_hostname); + parsedUri->proxy_hostname); curl_easy_setopt(ctx->curl_handle, CURLOPT_PROXYTYPE, - parsedQuery->proxy_type); + parsedUri->proxy_type); curl_easy_setopt(ctx->curl_handle, CURLOPT_PROXYPORT, - parsedQuery->proxy_port); + parsedUri->proxy_port); } if (virMutexInit(&ctx->curl_lock) < 0) { diff --git a/src/esx/esx_vi.h b/src/esx/esx_vi.h index ef9c6d93d2..325ba69c3f 100644 --- a/src/esx/esx_vi.h +++ b/src/esx/esx_vi.h @@ -168,8 +168,7 @@ int esxVI_Context_Alloc(esxVI_Context **ctx); void esxVI_Context_Free(esxVI_Context **ctx); int esxVI_Context_Connect(esxVI_Context *ctx, const char *ipAddress, const char *url, const char *username, - const char *password, - esxUtil_ParsedQuery *parsedQuery); + const char *password, esxUtil_ParsedUri *parsedUri); int esxVI_Context_DownloadFile(esxVI_Context *ctx, const char *url, char **content); int esxVI_Context_UploadFile(esxVI_Context *ctx, const char *url,