mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-03-07 17:28:15 +00:00
storage: add auth to virDomainDiskDef
Add additional fields to let you specify the how to authenticate with a disk. The secret to use may be referenced by a usage string or a UUID, i.e.: <auth username='myuser'> <secret type='ceph' usage='secretname'/> </auth> or <auth username='myuser'> <secret type='ceph' uuid='0a81f5b2-8403-7b23-c8d6-21ccc2f80d6f'/> </auth> Signed-off-by: Josh Durgin <josh.durgin@dreamhost.com>
This commit is contained in:
parent
536d1f8746
commit
5bd6271f59
1
AUTHORS
1
AUTHORS
@ -200,6 +200,7 @@ Patches have also been contributed by:
|
||||
Sage Weil <sage@newdream.net>
|
||||
David L Stevens <dlstevens@us.ibm.com>
|
||||
Tyler Coumbes <coumbes@gmail.com>
|
||||
Josh Durgin <josh.durgin@dreamhost.com>
|
||||
|
||||
[....send patches to get your name here....]
|
||||
|
||||
|
@ -913,6 +913,16 @@
|
||||
<transient/>
|
||||
<address type='drive' controller='0' bus='1' unit='0'/>
|
||||
</disk>
|
||||
<disk type='network'>
|
||||
<driver name="qemu" type="raw"/>
|
||||
<source protocol="rbd" name="image_name2">
|
||||
<host name="hostname" port="7000"/>
|
||||
</source>
|
||||
<target dev="hdd" bus="ide"/>
|
||||
<auth username='myuser'>
|
||||
<secret type='ceph' usage='mypassid'/>
|
||||
</auth>
|
||||
</disk>
|
||||
<disk type='block' device='cdrom'>
|
||||
<driver name='qemu' type='raw'/>
|
||||
<target def='hdc' bus='ide'/>
|
||||
@ -1160,7 +1170,24 @@
|
||||
"drive" controller, additional attributes
|
||||
<code>controller</code>, <code>bus</code>,
|
||||
and <code>unit</code> are available, each defaulting to 0.
|
||||
|
||||
</dd>
|
||||
<dt><code>auth</code></dt>
|
||||
<dd>If present, the <code>auth</code> element provides the
|
||||
authentication credentials needed to access the source. It
|
||||
includes a mandatory attribute <code>username</code>, which
|
||||
identifies the username to use during authentication, as well
|
||||
as a sub-element <code>secret</code> with mandatory
|
||||
attribute <code>type</code>, to tie back to
|
||||
a <a href="formatsecret.html">libvirt secret object</a> that
|
||||
holds the actual password or other credentials (the domain XML
|
||||
intentionally does not expose the password, only the reference
|
||||
to the object that does manage the password). For now, the
|
||||
only known secret <code>type</code> is "ceph", for Ceph RBD
|
||||
network sources, and requires either an
|
||||
attribute <code>uuid</code> with the UUID of the Ceph secret
|
||||
object, or an attribute <code>usage</code> with the name
|
||||
associated with the Ceph secret
|
||||
object. <span class="since">libvirt 0.9.7</span>
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
|
@ -602,6 +602,9 @@
|
||||
<optional>
|
||||
<ref name="driver"/>
|
||||
</optional>
|
||||
<optional>
|
||||
<ref name="diskAuth"/>
|
||||
</optional>
|
||||
<ref name="target"/>
|
||||
<optional>
|
||||
<ref name="deviceBoot"/>
|
||||
@ -2535,6 +2538,32 @@
|
||||
<empty/>
|
||||
</element>
|
||||
</define>
|
||||
<define name="diskAuth">
|
||||
<element name="auth">
|
||||
<attribute name="username">
|
||||
<ref name="genericName"/>
|
||||
</attribute>
|
||||
<ref name="diskAuthSecret"/>
|
||||
</element>
|
||||
</define>
|
||||
|
||||
<define name='diskAuthSecret'>
|
||||
<element name='secret'>
|
||||
<attribute name='type'>
|
||||
<choice>
|
||||
<value>ceph</value>
|
||||
</choice>
|
||||
</attribute>
|
||||
<choice>
|
||||
<attribute name='uuid'>
|
||||
<ref name="UUID"/>
|
||||
</attribute>
|
||||
<attribute name="usage">
|
||||
<ref name="genericName"/>
|
||||
</attribute>
|
||||
</choice>
|
||||
</element>
|
||||
</define>
|
||||
|
||||
<!--
|
||||
Optional hypervisor extensions in their own namespace:
|
||||
|
@ -1475,6 +1475,7 @@ libvirt_lxc_SOURCES = \
|
||||
$(NODE_INFO_SOURCES) \
|
||||
$(ENCRYPTION_CONF_SOURCES) \
|
||||
$(DOMAIN_CONF_SOURCES) \
|
||||
$(SECRET_CONF_SOURCES) \
|
||||
$(CPU_CONF_SOURCES) \
|
||||
$(NWFILTER_PARAM_CONF_SOURCES)
|
||||
libvirt_lxc_LDFLAGS = $(WARN_CFLAGS) $(AM_LDFLAGS)
|
||||
|
@ -49,6 +49,7 @@
|
||||
#include "virfile.h"
|
||||
#include "bitmap.h"
|
||||
#include "count-one-bits.h"
|
||||
#include "secret_conf.h"
|
||||
|
||||
#define VIR_FROM_THIS VIR_FROM_DOMAIN
|
||||
|
||||
@ -185,6 +186,11 @@ VIR_ENUM_IMPL(virDomainDiskProtocol, VIR_DOMAIN_DISK_PROTOCOL_LAST,
|
||||
"rbd",
|
||||
"sheepdog")
|
||||
|
||||
VIR_ENUM_IMPL(virDomainDiskSecretType, VIR_DOMAIN_DISK_SECRET_TYPE_LAST,
|
||||
"none",
|
||||
"uuid",
|
||||
"usage")
|
||||
|
||||
VIR_ENUM_IMPL(virDomainDiskIo, VIR_DOMAIN_DISK_IO_LAST,
|
||||
"default",
|
||||
"native",
|
||||
@ -788,6 +794,9 @@ void virDomainDiskDefFree(virDomainDiskDefPtr def)
|
||||
VIR_FREE(def->dst);
|
||||
VIR_FREE(def->driverName);
|
||||
VIR_FREE(def->driverType);
|
||||
VIR_FREE(def->auth.username);
|
||||
if (def->auth.secretType == VIR_DOMAIN_DISK_SECRET_TYPE_USAGE)
|
||||
VIR_FREE(def->auth.secret.usage);
|
||||
virStorageEncryptionFree(def->encryption);
|
||||
virDomainDeviceInfoClear(&def->info);
|
||||
|
||||
@ -2304,7 +2313,7 @@ virDomainDiskDefParseXML(virCapsPtr caps,
|
||||
unsigned int flags)
|
||||
{
|
||||
virDomainDiskDefPtr def;
|
||||
xmlNodePtr cur, host;
|
||||
xmlNodePtr cur, child;
|
||||
char *type = NULL;
|
||||
char *device = NULL;
|
||||
char *snapshot = NULL;
|
||||
@ -2326,6 +2335,10 @@ virDomainDiskDefParseXML(virCapsPtr caps,
|
||||
virStorageEncryptionPtr encryption = NULL;
|
||||
char *serial = NULL;
|
||||
char *startupPolicy = NULL;
|
||||
char *authUsername = NULL;
|
||||
char *authUsage = NULL;
|
||||
char *authUUID = NULL;
|
||||
char *usageType = NULL;
|
||||
|
||||
if (VIR_ALLOC(def) < 0) {
|
||||
virReportOOMError();
|
||||
@ -2382,10 +2395,10 @@ virDomainDiskDefParseXML(virCapsPtr caps,
|
||||
_("missing name for disk source"));
|
||||
goto error;
|
||||
}
|
||||
host = cur->children;
|
||||
while (host != NULL) {
|
||||
if (host->type == XML_ELEMENT_NODE &&
|
||||
xmlStrEqual(host->name, BAD_CAST "host")) {
|
||||
child = cur->children;
|
||||
while (child != NULL) {
|
||||
if (child->type == XML_ELEMENT_NODE &&
|
||||
xmlStrEqual(child->name, BAD_CAST "host")) {
|
||||
if (VIR_REALLOC_N(hosts, nhosts + 1) < 0) {
|
||||
virReportOOMError();
|
||||
goto error;
|
||||
@ -2394,20 +2407,20 @@ virDomainDiskDefParseXML(virCapsPtr caps,
|
||||
hosts[nhosts].port = NULL;
|
||||
nhosts++;
|
||||
|
||||
hosts[nhosts - 1].name = virXMLPropString(host, "name");
|
||||
hosts[nhosts - 1].name = virXMLPropString(child, "name");
|
||||
if (!hosts[nhosts - 1].name) {
|
||||
virDomainReportError(VIR_ERR_INTERNAL_ERROR,
|
||||
"%s", _("missing name for host"));
|
||||
goto error;
|
||||
}
|
||||
hosts[nhosts - 1].port = virXMLPropString(host, "port");
|
||||
hosts[nhosts - 1].port = virXMLPropString(child, "port");
|
||||
if (!hosts[nhosts - 1].port) {
|
||||
virDomainReportError(VIR_ERR_INTERNAL_ERROR,
|
||||
"%s", _("missing port for host"));
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
host = host->next;
|
||||
child = child->next;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@ -2444,6 +2457,58 @@ virDomainDiskDefParseXML(virCapsPtr caps,
|
||||
iotag = virXMLPropString(cur, "io");
|
||||
ioeventfd = virXMLPropString(cur, "ioeventfd");
|
||||
event_idx = virXMLPropString(cur, "event_idx");
|
||||
} else if (xmlStrEqual(cur->name, BAD_CAST "auth")) {
|
||||
authUsername = virXMLPropString(cur, "username");
|
||||
if (authUsername == NULL) {
|
||||
virDomainReportError(VIR_ERR_INTERNAL_ERROR,
|
||||
_("missing username for auth"));
|
||||
goto error;
|
||||
}
|
||||
|
||||
def->auth.secretType = VIR_DOMAIN_DISK_SECRET_TYPE_NONE;
|
||||
child = cur->children;
|
||||
while (child != NULL) {
|
||||
if (child->type == XML_ELEMENT_NODE &&
|
||||
xmlStrEqual(child->name, BAD_CAST "secret")) {
|
||||
usageType = virXMLPropString(child, "type");
|
||||
if (usageType == NULL) {
|
||||
virDomainReportError(VIR_ERR_XML_ERROR,
|
||||
_("missing type for secret"));
|
||||
goto error;
|
||||
}
|
||||
if (virSecretUsageTypeTypeFromString(usageType) !=
|
||||
VIR_SECRET_USAGE_TYPE_CEPH) {
|
||||
virDomainReportError(VIR_ERR_XML_ERROR,
|
||||
_("invalid secret type %s"),
|
||||
usageType);
|
||||
goto error;
|
||||
}
|
||||
|
||||
authUUID = virXMLPropString(child, "uuid");
|
||||
authUsage = virXMLPropString(child, "usage");
|
||||
|
||||
if (authUUID != NULL && authUsage != NULL) {
|
||||
virDomainReportError(VIR_ERR_XML_ERROR,
|
||||
_("only one of uuid and usage can be specfied"));
|
||||
goto error;
|
||||
}
|
||||
if (authUUID != NULL) {
|
||||
def->auth.secretType = VIR_DOMAIN_DISK_SECRET_TYPE_UUID;
|
||||
if (virUUIDParse(authUUID,
|
||||
def->auth.secret.uuid) < 0) {
|
||||
virDomainReportError(VIR_ERR_XML_ERROR,
|
||||
_("malformed uuid %s"),
|
||||
authUUID);
|
||||
goto error;
|
||||
}
|
||||
} else if (authUsage != NULL) {
|
||||
def->auth.secretType = VIR_DOMAIN_DISK_SECRET_TYPE_USAGE;
|
||||
def->auth.secret.usage = authUsage;
|
||||
authUsage = NULL;
|
||||
}
|
||||
}
|
||||
child = child->next;
|
||||
}
|
||||
} else if (xmlStrEqual(cur->name, BAD_CAST "readonly")) {
|
||||
def->readonly = 1;
|
||||
} else if (xmlStrEqual(cur->name, BAD_CAST "shareable")) {
|
||||
@ -2683,6 +2748,8 @@ virDomainDiskDefParseXML(virCapsPtr caps,
|
||||
hosts = NULL;
|
||||
def->nhosts = nhosts;
|
||||
nhosts = 0;
|
||||
def->auth.username = authUsername;
|
||||
authUsername = NULL;
|
||||
def->driverName = driverName;
|
||||
driverName = NULL;
|
||||
def->driverType = driverType;
|
||||
@ -2719,6 +2786,10 @@ cleanup:
|
||||
VIR_FREE(hosts);
|
||||
VIR_FREE(protocol);
|
||||
VIR_FREE(device);
|
||||
VIR_FREE(authUsername);
|
||||
VIR_FREE(usageType);
|
||||
VIR_FREE(authUUID);
|
||||
VIR_FREE(authUsage);
|
||||
VIR_FREE(driverType);
|
||||
VIR_FREE(driverName);
|
||||
VIR_FREE(cachetag);
|
||||
@ -9208,6 +9279,8 @@ virDomainDiskDefFormat(virBufferPtr buf,
|
||||
const char *event_idx = virDomainVirtioEventIdxTypeToString(def->event_idx);
|
||||
const char *startupPolicy = virDomainStartupPolicyTypeToString(def->startupPolicy);
|
||||
|
||||
char uuidstr[VIR_UUID_STRING_BUFLEN];
|
||||
|
||||
if (!type) {
|
||||
virDomainReportError(VIR_ERR_INTERNAL_ERROR,
|
||||
_("unexpected disk type %d"), def->type);
|
||||
@ -9265,6 +9338,23 @@ virDomainDiskDefFormat(virBufferPtr buf,
|
||||
virBufferAddLit(buf, "/>\n");
|
||||
}
|
||||
|
||||
if (def->auth.username) {
|
||||
virBufferEscapeString(buf, " <auth username='%s'>\n",
|
||||
def->auth.username);
|
||||
if (def->auth.secretType == VIR_DOMAIN_DISK_SECRET_TYPE_UUID) {
|
||||
virUUIDFormat(def->auth.secret.uuid, uuidstr);
|
||||
virBufferAsprintf(buf,
|
||||
" <secret type='ceph' uuid='%s'/>\n",
|
||||
uuidstr);
|
||||
}
|
||||
if (def->auth.secretType == VIR_DOMAIN_DISK_SECRET_TYPE_USAGE) {
|
||||
virBufferEscapeString(buf,
|
||||
" <secret type='ceph' usage='%s'/>\n",
|
||||
def->auth.secret.usage);
|
||||
}
|
||||
virBufferAddLit(buf, " </auth>\n");
|
||||
}
|
||||
|
||||
if (def->src || def->nhosts > 0 ||
|
||||
def->startupPolicy) {
|
||||
switch (def->type) {
|
||||
|
@ -278,6 +278,14 @@ enum virDomainStartupPolicy {
|
||||
VIR_DOMAIN_STARTUP_POLICY_LAST
|
||||
};
|
||||
|
||||
enum virDomainDiskSecretType {
|
||||
VIR_DOMAIN_DISK_SECRET_TYPE_NONE,
|
||||
VIR_DOMAIN_DISK_SECRET_TYPE_UUID,
|
||||
VIR_DOMAIN_DISK_SECRET_TYPE_USAGE,
|
||||
|
||||
VIR_DOMAIN_DISK_SECRET_TYPE_LAST
|
||||
};
|
||||
|
||||
/* Stores the virtual disk configuration */
|
||||
typedef struct _virDomainDiskDef virDomainDiskDef;
|
||||
typedef virDomainDiskDef *virDomainDiskDefPtr;
|
||||
@ -290,6 +298,14 @@ struct _virDomainDiskDef {
|
||||
int protocol;
|
||||
int nhosts;
|
||||
virDomainDiskHostDefPtr hosts;
|
||||
struct {
|
||||
char *username;
|
||||
int secretType; /* enum virDomainDiskSecretType */
|
||||
union {
|
||||
unsigned char uuid[VIR_UUID_BUFLEN];
|
||||
char *usage;
|
||||
} secret;
|
||||
} auth;
|
||||
char *driverName;
|
||||
char *driverType;
|
||||
char *serial;
|
||||
@ -1881,6 +1897,7 @@ VIR_ENUM_DECL(virDomainDiskCache)
|
||||
VIR_ENUM_DECL(virDomainDiskErrorPolicy)
|
||||
VIR_ENUM_DECL(virDomainDiskProtocol)
|
||||
VIR_ENUM_DECL(virDomainDiskIo)
|
||||
VIR_ENUM_DECL(virDomainDiskSecretType)
|
||||
VIR_ENUM_DECL(virDomainDiskSnapshot)
|
||||
VIR_ENUM_DECL(virDomainIoEventFd)
|
||||
VIR_ENUM_DECL(virDomainVirtioEventIdx)
|
||||
|
@ -930,6 +930,8 @@ virSecretDefFormat;
|
||||
virSecretDefFree;
|
||||
virSecretDefParseFile;
|
||||
virSecretDefParseString;
|
||||
virSecretUsageTypeTypeFromString;
|
||||
virSecretUsageTypeTypeToString;
|
||||
|
||||
|
||||
# security_driver.h
|
||||
|
Loading…
x
Reference in New Issue
Block a user