esx: implement domainInterfaceAddresses

Implement the .domainInterfaceAddresses hypervisor API, although only
functional for the VIR_DOMAIN_INTERFACE_ADDRESSES_SRC_AGENT source.

Signed-off-by: Pino Toscano <ptoscano@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
This commit is contained in:
Pino Toscano 2020-09-14 11:11:38 +02:00
parent 7ad86c849f
commit 66732236a4
2 changed files with 174 additions and 0 deletions

View File

@ -799,6 +799,10 @@ Enter administrator password for example-vcenter.com:
<li>
<code>virDomainGetHostname</code>
</li>
<li>
<code>virDomainInterfaceAddresses</code> (only for the
<code>VIR_DOMAIN_INTERFACE_ADDRESSES_SRC_AGENT</code> source)
</li>
<li>
<code>virDomainReboot</code>
</li>

View File

@ -5113,6 +5113,175 @@ esxDomainGetHostname(virDomainPtr domain,
}
static int
esxParseIPAddress(const char *ipAddress, int prefixLength,
virDomainIPAddress *addr)
{
virSocketAddr tmp_addr;
virIPAddrType addr_type;
if (virSocketAddrParseAny(&tmp_addr, ipAddress, AF_UNSPEC, false) <= 0)
return 0;
switch (VIR_SOCKET_ADDR_FAMILY(&tmp_addr)) {
case AF_INET:
addr_type = VIR_IP_ADDR_TYPE_IPV4;
break;
case AF_INET6:
addr_type = VIR_IP_ADDR_TYPE_IPV6;
break;
default:
return 0;
}
addr->type = addr_type;
addr->addr = g_strdup(ipAddress);
addr->prefix = prefixLength;
return 1;
}
static int
esxDomainInterfaceAddresses(virDomainPtr domain,
virDomainInterfacePtr **ifaces,
unsigned int source,
unsigned int flags)
{
int result = -1;
esxPrivate *priv = domain->conn->privateData;
esxVI_String *propertyNameList = NULL;
esxVI_ObjectContent *virtualMachine = NULL;
esxVI_VirtualMachinePowerState powerState;
esxVI_DynamicProperty *dynamicProperty;
esxVI_GuestNicInfo *guestNicInfoList = NULL;
esxVI_GuestNicInfo *guestNicInfo = NULL;
virDomainInterfacePtr *ifaces_ret = NULL;
size_t ifaces_count = 0;
size_t i;
int ret;
virCheckFlags(0, -1);
if (source != VIR_DOMAIN_INTERFACE_ADDRESSES_SRC_AGENT) {
virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED,
_("Unknown IP address data source %d"),
source);
return -1;
}
if (esxVI_EnsureSession(priv->primary) < 0)
return -1;
if (esxVI_String_AppendValueListToList(&propertyNameList,
"runtime.powerState\0"
"guest.net") < 0 ||
esxVI_LookupVirtualMachineByUuid(priv->primary, domain->uuid,
propertyNameList, &virtualMachine,
esxVI_Occurrence_RequiredItem) ||
esxVI_GetVirtualMachinePowerState(virtualMachine, &powerState) < 0) {
goto cleanup;
}
if (powerState != esxVI_VirtualMachinePowerState_PoweredOn) {
virReportError(VIR_ERR_OPERATION_INVALID, "%s",
_("Domain is not powered on"));
goto cleanup;
}
for (dynamicProperty = virtualMachine->propSet; dynamicProperty;
dynamicProperty = dynamicProperty->_next) {
if (STREQ(dynamicProperty->name, "guest.net")) {
if (esxVI_GuestNicInfo_CastListFromAnyType
(dynamicProperty->val, &guestNicInfoList) < 0) {
goto cleanup;
}
}
}
if (!guestNicInfoList) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("Missing property '%s' in answer"),
"guest.net");
goto cleanup;
}
for (guestNicInfo = guestNicInfoList; guestNicInfo;
guestNicInfo = guestNicInfo->_next) {
virDomainInterfacePtr iface = NULL;
size_t addrs_count = 0;
if (guestNicInfo->connected != esxVI_Boolean_True ||
!guestNicInfo->network) {
continue;
}
if (VIR_EXPAND_N(ifaces_ret, ifaces_count, 1) < 0)
goto cleanup;
if (VIR_ALLOC(ifaces_ret[ifaces_count - 1]) < 0)
goto cleanup;
iface = ifaces_ret[ifaces_count - 1];
iface->naddrs = 0;
iface->name = g_strdup(guestNicInfo->network);
iface->hwaddr = g_strdup(guestNicInfo->macAddress);
if (guestNicInfo->ipConfig) {
esxVI_NetIpConfigInfoIpAddress *ipAddress;
for (ipAddress = guestNicInfo->ipConfig->ipAddress; ipAddress;
ipAddress = ipAddress->_next) {
virDomainIPAddress ip_addr;
ret = esxParseIPAddress(ipAddress->ipAddress,
ipAddress->prefixLength->value, &ip_addr);
if (ret < 0)
goto cleanup;
else if (ret == 0)
continue;
if (VIR_APPEND_ELEMENT(iface->addrs, addrs_count, ip_addr) < 0)
goto cleanup;
}
} else {
esxVI_String *str;
for (str = guestNicInfo->ipAddress; str;
str = str->_next) {
virDomainIPAddress ip_addr;
/* Not even the netmask seems available... */
ret = esxParseIPAddress(str->value, 0, &ip_addr);
if (ret < 0)
goto cleanup;
else if (ret == 0)
continue;
if (VIR_APPEND_ELEMENT(iface->addrs, addrs_count, ip_addr) < 0)
goto cleanup;
}
}
iface->naddrs = addrs_count;
}
*ifaces = ifaces_ret;
result = ifaces_count;
cleanup:
if (result < 0) {
if (ifaces_ret) {
for (i = 0; i < ifaces_count; i++)
virDomainInterfaceFree(ifaces_ret[i]);
}
}
esxVI_String_Free(&propertyNameList);
esxVI_ObjectContent_Free(&virtualMachine);
esxVI_GuestNicInfo_Free(&guestNicInfoList);
return result;
}
static virHypervisorDriver esxHypervisorDriver = {
.name = "ESX",
.connectOpen = esxConnectOpen, /* 0.7.0 */
@ -5194,6 +5363,7 @@ static virHypervisorDriver esxHypervisorDriver = {
.connectIsAlive = esxConnectIsAlive, /* 0.9.8 */
.domainHasManagedSaveImage = esxDomainHasManagedSaveImage, /* 1.2.13 */
.domainGetHostname = esxDomainGetHostname, /* 6.8.0 */
.domainInterfaceAddresses = esxDomainInterfaceAddresses, /* 6.8.0 */
};